Report fatal errors on android logcat. Check for allocation failure.

PiperOrigin-RevId: 362328919
diff --git a/cmake/bazel_to_cmake.py b/cmake/bazel_to_cmake.py
index ba1a38b..2148f99 100755
--- a/cmake/bazel_to_cmake.py
+++ b/cmake/bazel_to_cmake.py
@@ -49,7 +49,7 @@
     ['selects.config_setting_group', 'config_setting_group'],
     ['@com_google_googletest//:gtest', 'gtest'],
     ['@com_google_googletest//:gtest_main', 'gtest_main'],
-    ['@cpuinfo//:cpuinfo_with_unstripped_include_path', 'cpuinfo'],
+    ['@cpuinfo', 'cpuinfo'],
 ]
 
 
@@ -81,6 +81,8 @@
             condition = 'CMAKE_SYSTEM_PROCESSOR STREQUAL s390 OR CMAKE_SYSTEM_PROCESSOR STREQUAL s390x'
         elif re.search(r':fuchsia$', key):
             condition = 'CMAKE_SYSTEM_NAME STREQUAL Fuchsia'
+        elif re.search(r':android$', key):
+            condition = 'CMAKE_SYSTEM_NAME STREQUAL Android'
         elif re.search(r':arm32_assuming_neon$', key):
             condition = 'CMAKE_SYSTEM_PROCESSOR STREQUAL arm'
         elif re.search(r':do_not_want_O3$', key):
diff --git a/ruy/BUILD b/ruy/BUILD
index 37e89ab..fc41fe0 100644
--- a/ruy/BUILD
+++ b/ruy/BUILD
@@ -71,6 +71,11 @@
 )
 
 config_setting(
+    name = "android",
+    values = {"crosstool_top": "//external:android/crosstool"},
+)
+
+config_setting(
     name = "dbg_build",
     values = {
         "compilation_mode": "dbg",
@@ -122,8 +127,13 @@
 
 cc_library(
     name = "check_macros",
+    srcs = ["check_macros.cc"],
     hdrs = ["check_macros.h"],
     copts = ruy_copts(),
+    linkopts = select({
+        ":android": ["-llog"],
+        "//conditions:default": [],
+    }),
 )
 
 cc_test(
@@ -213,6 +223,18 @@
         "system_aligned_alloc.h",
     ],
     copts = ruy_copts(),
+    deps = [":check_macros"],
+)
+
+cc_test(
+    name = "system_aligned_alloc_test",
+    srcs = ["system_aligned_alloc_test.cc"],
+    copts = ruy_copts(),
+    deps = [
+        ":check_macros",
+        ":gtest_wrapper",
+        ":system_aligned_alloc",
+    ],
 )
 
 cc_library(
diff --git a/ruy/CMakeLists.txt b/ruy/CMakeLists.txt
index 4c3e394..639fd91 100644
--- a/ruy/CMakeLists.txt
+++ b/ruy/CMakeLists.txt
@@ -58,15 +58,25 @@
     gtest
 )
 
+if(CMAKE_SYSTEM_NAME STREQUAL Android)
+  set(ruy_3_llog "-llog")
+else()
+  set(ruy_3_llog "")
+endif()
+
 ruy_cc_library(
   NAME
     ruy_check_macros
+  SRCS
+    check_macros.cc
   HDRS
     check_macros.h
   COPTS
     ${ruy_0_Wall_Wcxx14_compat_Wextra_Wundef}
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
+  LINKOPTS
+    ${ruy_3_llog}
 )
 
 ruy_cc_test(
@@ -106,9 +116,9 @@
 )
 
 if(CMAKE_SYSTEM_NAME STREQUAL Windows)
-  set(ruy_3_pthread "")
+  set(ruy_4_pthread "")
 else()
-  set(ruy_3_pthread "-pthread")
+  set(ruy_4_pthread "-pthread")
 endif()
 
 ruy_cc_library(
@@ -123,7 +133,7 @@
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
   LINKOPTS
-    ${ruy_3_pthread}
+    ${ruy_4_pthread}
   DEPS
     ruy_time
 )
@@ -138,7 +148,7 @@
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
   LINKOPTS
-    ${ruy_3_pthread}
+    ${ruy_4_pthread}
   DEPS
     ruy_gtest_wrapper
     ruy_platform
@@ -202,6 +212,23 @@
     ${ruy_0_Wall_Wcxx14_compat_Wextra_Wundef}
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
+  DEPS
+    ruy_check_macros
+)
+
+ruy_cc_test(
+  NAME
+    ruy_system_aligned_alloc_test
+  SRCS
+    system_aligned_alloc_test.cc
+  COPTS
+    ${ruy_0_Wall_Wcxx14_compat_Wextra_Wundef}
+    ${ruy_1_mfpu_neon}
+    ${ruy_2_O3}
+  DEPS
+    ruy_check_macros
+    ruy_gtest_wrapper
+    ruy_system_aligned_alloc
 )
 
 ruy_cc_library(
@@ -352,7 +379,7 @@
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
   LINKOPTS
-    ${ruy_3_pthread}
+    ${ruy_4_pthread}
   DEPS
     ruy_check_macros
     ruy_time
@@ -371,7 +398,7 @@
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
   LINKOPTS
-    ${ruy_3_pthread}
+    ${ruy_4_pthread}
   PUBLIC
   DEPS
     ruy_blocking_counter
@@ -393,29 +420,29 @@
 )
 
 if(CMAKE_SYSTEM_NAME STREQUAL Windows)
-  set(ruy_4_Wno_undef "")
+  set(ruy_5_Wno_undef "")
 else()
-  set(ruy_4_Wno_undef "-Wno-undef")
+  set(ruy_5_Wno_undef "-Wno-undef")
 endif()
 
 if(CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64le)
-  set(ruy_5_DRUY_HAVE_CPUINFO "")
+  set(ruy_6_DRUY_HAVE_CPUINFO "")
 elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL s390 OR CMAKE_SYSTEM_PROCESSOR STREQUAL s390x)
-  set(ruy_5_DRUY_HAVE_CPUINFO "")
+  set(ruy_6_DRUY_HAVE_CPUINFO "")
 elseif(CMAKE_SYSTEM_NAME STREQUAL Fuchsia)
-  set(ruy_5_DRUY_HAVE_CPUINFO "")
+  set(ruy_6_DRUY_HAVE_CPUINFO "")
 else()
-  set(ruy_5_DRUY_HAVE_CPUINFO "-DRUY_HAVE_CPUINFO")
+  set(ruy_6_DRUY_HAVE_CPUINFO "-DRUY_HAVE_CPUINFO")
 endif()
 
 if(CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64le)
-  set(ruy_6_cpuinfo "")
+  set(ruy_7_cpuinfo "")
 elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL s390 OR CMAKE_SYSTEM_PROCESSOR STREQUAL s390x)
-  set(ruy_6_cpuinfo "")
+  set(ruy_7_cpuinfo "")
 elseif(CMAKE_SYSTEM_NAME STREQUAL Fuchsia)
-  set(ruy_6_cpuinfo "")
+  set(ruy_7_cpuinfo "")
 else()
-  set(ruy_6_cpuinfo "cpuinfo")
+  set(ruy_7_cpuinfo "cpuinfo")
 endif()
 
 ruy_cc_library(
@@ -429,13 +456,13 @@
     ${ruy_0_Wall_Wcxx14_compat_Wextra_Wundef}
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
-    ${ruy_4_Wno_undef}
-    ${ruy_5_DRUY_HAVE_CPUINFO}
+    ${ruy_5_Wno_undef}
+    ${ruy_6_DRUY_HAVE_CPUINFO}
   DEPS
     ruy_platform
     ruy_check_macros
     ruy_cpu_cache_params
-    ${ruy_6_cpuinfo}
+    ${ruy_7_cpuinfo}
 )
 
 ruy_cc_library(
@@ -676,11 +703,11 @@
 )
 
 if((CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL amd64) AND NOT MSVC)
-  set(ruy_7_mavx512bw_mavx512cd_mavx512dq_mavx512f_mavx512vl_arch_AVX512 ";-mavx512f;-mavx512vl;-mavx512cd;-mavx512bw;-mavx512dq")
+  set(ruy_8_mavx512bw_mavx512cd_mavx512dq_mavx512f_mavx512vl_arch_AVX512 ";-mavx512f;-mavx512vl;-mavx512cd;-mavx512bw;-mavx512dq")
 elseif(MSVC)
-  set(ruy_7_mavx512bw_mavx512cd_mavx512dq_mavx512f_mavx512vl_arch_AVX512 "/arch:AVX512")
+  set(ruy_8_mavx512bw_mavx512cd_mavx512dq_mavx512f_mavx512vl_arch_AVX512 "/arch:AVX512")
 else()
-  set(ruy_7_mavx512bw_mavx512cd_mavx512dq_mavx512f_mavx512vl_arch_AVX512 "")
+  set(ruy_8_mavx512bw_mavx512cd_mavx512dq_mavx512f_mavx512vl_arch_AVX512 "")
 endif()
 
 ruy_cc_library(
@@ -694,7 +721,7 @@
     ${ruy_0_Wall_Wcxx14_compat_Wextra_Wundef}
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
-    ${ruy_7_mavx512bw_mavx512cd_mavx512dq_mavx512f_mavx512vl_arch_AVX512}
+    ${ruy_8_mavx512bw_mavx512cd_mavx512dq_mavx512f_mavx512vl_arch_AVX512}
   DEPS
     ruy_check_macros
     ruy_kernel_common
@@ -718,7 +745,7 @@
     ${ruy_0_Wall_Wcxx14_compat_Wextra_Wundef}
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
-    ${ruy_7_mavx512bw_mavx512cd_mavx512dq_mavx512f_mavx512vl_arch_AVX512}
+    ${ruy_8_mavx512bw_mavx512cd_mavx512dq_mavx512f_mavx512vl_arch_AVX512}
   DEPS
     ruy_check_macros
     ruy_mat
@@ -741,18 +768,18 @@
     ${ruy_0_Wall_Wcxx14_compat_Wextra_Wundef}
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
-    ${ruy_7_mavx512bw_mavx512cd_mavx512dq_mavx512f_mavx512vl_arch_AVX512}
+    ${ruy_8_mavx512bw_mavx512cd_mavx512dq_mavx512f_mavx512vl_arch_AVX512}
   DEPS
     ruy_opt_set
     ruy_platform
 )
 
 if((CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL amd64) AND NOT MSVC)
-  set(ruy_8_mavx2_mfma_arch_AVX2 "-mavx2;-mfma")
+  set(ruy_9_mavx2_mfma_arch_AVX2 "-mavx2;-mfma")
 elseif(MSVC)
-  set(ruy_8_mavx2_mfma_arch_AVX2 "/arch:AVX2")
+  set(ruy_9_mavx2_mfma_arch_AVX2 "/arch:AVX2")
 else()
-  set(ruy_8_mavx2_mfma_arch_AVX2 "")
+  set(ruy_9_mavx2_mfma_arch_AVX2 "")
 endif()
 
 ruy_cc_library(
@@ -766,7 +793,7 @@
     ${ruy_0_Wall_Wcxx14_compat_Wextra_Wundef}
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
-    ${ruy_8_mavx2_mfma_arch_AVX2}
+    ${ruy_9_mavx2_mfma_arch_AVX2}
   DEPS
     ruy_check_macros
     ruy_kernel_common
@@ -790,7 +817,7 @@
     ${ruy_0_Wall_Wcxx14_compat_Wextra_Wundef}
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
-    ${ruy_8_mavx2_mfma_arch_AVX2}
+    ${ruy_9_mavx2_mfma_arch_AVX2}
   DEPS
     ruy_check_macros
     ruy_mat
@@ -813,18 +840,18 @@
     ${ruy_0_Wall_Wcxx14_compat_Wextra_Wundef}
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
-    ${ruy_8_mavx2_mfma_arch_AVX2}
+    ${ruy_9_mavx2_mfma_arch_AVX2}
   DEPS
     ruy_opt_set
     ruy_platform
 )
 
 if((CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL amd64) AND NOT MSVC)
-  set(ruy_9_mavx_arch_AVX "-mavx")
+  set(ruy_10_mavx_arch_AVX "-mavx")
 elseif(MSVC)
-  set(ruy_9_mavx_arch_AVX "/arch:AVX")
+  set(ruy_10_mavx_arch_AVX "/arch:AVX")
 else()
-  set(ruy_9_mavx_arch_AVX "")
+  set(ruy_10_mavx_arch_AVX "")
 endif()
 
 ruy_cc_library(
@@ -838,7 +865,7 @@
     ${ruy_0_Wall_Wcxx14_compat_Wextra_Wundef}
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
-    ${ruy_9_mavx_arch_AVX}
+    ${ruy_10_mavx_arch_AVX}
   DEPS
     ruy_check_macros
     ruy_kernel_common
@@ -862,7 +889,7 @@
     ${ruy_0_Wall_Wcxx14_compat_Wextra_Wundef}
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
-    ${ruy_9_mavx_arch_AVX}
+    ${ruy_10_mavx_arch_AVX}
   DEPS
     ruy_check_macros
     ruy_mat
@@ -885,7 +912,7 @@
     ${ruy_0_Wall_Wcxx14_compat_Wextra_Wundef}
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
-    ${ruy_9_mavx_arch_AVX}
+    ${ruy_10_mavx_arch_AVX}
   DEPS
     ruy_opt_set
     ruy_platform
@@ -1282,9 +1309,9 @@
 )
 
 if(CMAKE_SYSTEM_NAME STREQUAL Windows)
-  set(ruy_10_lm "")
+  set(ruy_11_lm "")
 else()
-  set(ruy_10_lm "-lm")
+  set(ruy_11_lm "-lm")
 endif()
 
 ruy_cc_library(
@@ -1298,7 +1325,7 @@
     ${ruy_1_mfpu_neon}
     ${ruy_2_O3}
   LINKOPTS
-    ${ruy_10_lm}
+    ${ruy_11_lm}
   DEPS
     ruy_allocator
     ruy_size_util
diff --git a/ruy/check_macros.cc b/ruy/check_macros.cc
new file mode 100644
index 0000000..dc47c88
--- /dev/null
+++ b/ruy/check_macros.cc
@@ -0,0 +1,52 @@
+/* Copyright 2019 Google LLC. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "ruy/check_macros.h"
+
+#ifdef __ANDROID__
+#include <android/log.h>
+#endif
+
+namespace ruy {
+namespace check_macros {
+
+void FatalError(const char *format, ...) {
+  va_list args;
+  va_start(args, format);
+
+  {
+    va_list args_for_vfprintf;
+    va_copy(args_for_vfprintf, args);
+    vfprintf(stderr, format, args_for_vfprintf);
+    va_end(args_for_vfprintf);
+  }
+
+#ifdef __ANDROID__
+  {
+    va_list args_for_android_log_vprint;
+    va_copy(args_for_android_log_vprint, args);
+    __android_log_vprint(ANDROID_LOG_FATAL, "ruy", format,
+                         args_for_android_log_vprint);
+    va_end(args_for_android_log_vprint);
+  }
+#endif
+
+  va_end(args);
+
+  abort();
+}
+
+}  // end namespace check_macros
+}  // end namespace ruy
diff --git a/ruy/check_macros.h b/ruy/check_macros.h
index 13d27e2..3491841 100644
--- a/ruy/check_macros.h
+++ b/ruy/check_macros.h
@@ -18,6 +18,7 @@
 #ifndef RUY_RUY_CHECK_MACROS_H_
 #define RUY_RUY_CHECK_MACROS_H_
 
+#include <cstdarg>
 #include <cstdio>
 #include <cstdlib>
 #include <functional>
@@ -68,12 +69,13 @@
   }
 };
 
+void FatalError(const char* format, ...);
+
 inline void CheckImpl(bool condition, const char* file, int line,
                       const char* macro, const char* condition_str) {
   if (!condition) {
-    fprintf(stderr, "%s:%d: %s condition not satisfied: %s\n", file, line,
-            macro, condition_str);
-    abort();
+    FatalError("%s:%d: %s condition not satisfied: %s\n", file, line, macro,
+               condition_str);
   }
 }
 
@@ -89,16 +91,18 @@
     ToString<LhsType>::Run(lhs_value, lhs_value_buf);
     char rhs_value_buf[kValueBufSize];
     ToString<RhsType>::Run(rhs_value, rhs_value_buf);
-    fprintf(
-        stderr,
+    FatalError(
         "%s:%d: %s condition not satisfied:   [ %s %s %s ]   with values   [ "
         "%s %s %s ].\n",
         file, line, macro, lhs, op_symbol, rhs, lhs_value_buf, op_symbol,
         rhs_value_buf);
-    abort();
   }
 }
 
+#define RUY_FATAL_ERROR(format, ...)                                       \
+  ruy::check_macros::FatalError("%s:%d: " format "\n", __FILE__, __LINE__, \
+                                __VA_ARGS__);
+
 #define RUY_CHECK_IMPL(macro, condition)                              \
   ruy::check_macros::CheckImpl(condition, __FILE__, __LINE__, #macro, \
                                #condition)
diff --git a/ruy/system_aligned_alloc.cc b/ruy/system_aligned_alloc.cc
index 7c86691..bdcc17b 100644
--- a/ruy/system_aligned_alloc.cc
+++ b/ruy/system_aligned_alloc.cc
@@ -16,17 +16,20 @@
 #include "ruy/system_aligned_alloc.h"
 
 #include <cstddef>
+#include <cstdio>
 #include <cstdlib>
 
 #ifdef _WIN32
 #include <malloc.h>
 #endif
 
+#include "ruy/check_macros.h"
+
 namespace ruy {
-
 namespace detail {
+namespace {
 
-void *SystemAlignedAlloc(std::ptrdiff_t num_bytes) {
+void *RawSystemAlignedAlloc(std::ptrdiff_t num_bytes) {
 #ifdef _WIN32
   return _aligned_malloc(num_bytes, kMinimumBlockAlignment);
 #else
@@ -38,6 +41,16 @@
 #endif
 }
 
+}  // namespace
+
+void *SystemAlignedAlloc(std::ptrdiff_t num_bytes) {
+  void *ptr = RawSystemAlignedAlloc(num_bytes);
+  if (!ptr) {
+    RUY_FATAL_ERROR("failed to allocate %td bytes", num_bytes);
+  }
+  return ptr;
+}
+
 void SystemAlignedFree(void *ptr) {
 #ifdef _WIN32
   _aligned_free(ptr);
@@ -47,5 +60,4 @@
 }
 
 }  // namespace detail
-
 }  // namespace ruy
diff --git a/ruy/system_aligned_alloc_test.cc b/ruy/system_aligned_alloc_test.cc
new file mode 100644
index 0000000..f21b4fd
--- /dev/null
+++ b/ruy/system_aligned_alloc_test.cc
@@ -0,0 +1,45 @@
+/* Copyright 2019 Google LLC. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "ruy/system_aligned_alloc.h"
+
+#include <cstdint>
+#include <type_traits>
+
+#include "ruy/check_macros.h"
+#include "ruy/gtest_wrapper.h"
+
+namespace ruy {
+namespace detail {
+namespace {
+
+TEST(SystemAlignedAllocTest, SystemAlignedAllocTest) {
+  for (std::ptrdiff_t size = 1; size < 10000; size++) {
+    void* ptr = SystemAlignedAlloc(size);
+    RUY_CHECK(ptr);
+    RUY_CHECK(
+        !(reinterpret_cast<std::uintptr_t>(ptr) % kMinimumBlockAlignment));
+    SystemAlignedFree(ptr);
+  }
+}
+
+}  // namespace
+}  // namespace detail
+}  // namespace ruy
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}