Add tvm::support::hexdump() debug utility (#6154)
authorAndrew Reusch <areusch@octoml.ai>
Tue, 18 Aug 2020 23:20:38 +0000 (16:20 -0700)
committerGitHub <noreply@github.com>
Tue, 18 Aug 2020 23:20:38 +0000 (16:20 -0700)
CMakeLists.txt
src/support/hexdump.cc [new file with mode: 0644]
src/support/hexdump.h [new file with mode: 0644]
tests/cpp/support_test.cc [new file with mode: 0644]

index 90174d5..d2ce02c 100644 (file)
@@ -116,10 +116,10 @@ else(MSVC)
     set(CMAKE_C_FLAGS "-O2 -Wall -fPIC ${CMAKE_C_FLAGS}")
     set(CMAKE_CXX_FLAGS "-O2 -Wall -fPIC ${CMAKE_CXX_FLAGS}")
     set(CMAKE_CUDA_FLAGS "-O2 -Xcompiler=-Wall -Xcompiler=-fPIC ${CMAKE_CUDA_FLAGS}")
+    set(TVM_VISIBILITY_FLAG "")
     if (HIDE_PRIVATE_SYMBOLS)
       message(STATUS "Hide private symbols...")
-      set(CMAKE_C_FLAGS "-fvisibility=hidden ${CMAKE_C_FLAGS}")
-      set(CMAKE_CXX_FLAGS "-fvisibility=hidden ${CMAKE_CXX_FLAGS}")
+      set(TVM_VISIBILITY_FLAG "-fvisibility=hidden")
     endif(HIDE_PRIVATE_SYMBOLS)
   endif ()
   if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND
@@ -336,8 +336,13 @@ endif()
 
 add_lib_info(${CMAKE_CURRENT_LIST_DIR}/src/support/libinfo.cc)
 
-add_library(tvm SHARED ${COMPILER_SRCS} ${RUNTIME_SRCS})
-add_library(tvm_runtime SHARED ${RUNTIME_SRCS})
+add_library(tvm_objs OBJECT ${COMPILER_SRCS} ${RUNTIME_SRCS})
+add_library(tvm_runtime_objs OBJECT ${RUNTIME_SRCS})
+
+add_library(tvm SHARED $<TARGET_OBJECTS:tvm_objs>)
+set_property(TARGET tvm APPEND PROPERTY LINK_OPTIONS "${TVM_VISIBILITY_FLAGS}")
+add_library(tvm_runtime SHARED $<TARGET_OBJECTS:tvm_runtime_objs>)
+set_property(TARGET tvm_runtime APPEND PROPERTY LINK_OPTIONS "${TVM_VISIBILITY_FLAGS}")
 
 if(USE_CPP_RPC)
   add_subdirectory("apps/cpp_rpc")
@@ -345,18 +350,18 @@ endif()
 
 if(USE_RELAY_DEBUG)
   message(STATUS "Building Relay in debug mode...")
-  set_target_properties(tvm PROPERTIES COMPILE_DEFINITIONS "USE_RELAY_DEBUG")
-  set_target_properties(tvm PROPERTIES COMPILE_DEFINITIONS "DMLC_LOG_DEBUG")
+  set_target_properties(tvm_objs PROPERTIES COMPILE_DEFINITIONS "USE_RELAY_DEBUG")
+  set_target_properties(tvm_objs PROPERTIES COMPILE_DEFINITIONS "DMLC_LOG_DEBUG")
 else()
-  set_target_properties(tvm PROPERTIES COMPILE_DEFINITIONS "NDEBUG")
+  set_target_properties(tvm_objs PROPERTIES COMPILE_DEFINITIONS "NDEBUG")
 endif(USE_RELAY_DEBUG)
 
 if(USE_FALLBACK_STL_MAP)
   message(STATUS "Building with STL Map...")
-  set_target_properties(tvm PROPERTIES COMPILE_DEFINITIONS "USE_FALLBACK_STL_MAP=1")
+  set_target_properties(tvm_objs PROPERTIES COMPILE_DEFINITIONS "USE_FALLBACK_STL_MAP=1")
 else()
   message(STATUS "Building with TVM Map...")
-  set_target_properties(tvm PROPERTIES COMPILE_DEFINITIONS "USE_FALLBACK_STL_MAP=0")
+  set_target_properties(tvm_objs PROPERTIES COMPILE_DEFINITIONS "USE_FALLBACK_STL_MAP=0")
 endif(USE_FALLBACK_STL_MAP)
 
 if(BUILD_FOR_HEXAGON)
@@ -383,8 +388,22 @@ endif()
 target_link_libraries(tvm ${TVM_LINKER_LIBS} ${TVM_RUNTIME_LINKER_LIBS})
 target_link_libraries(tvm_runtime ${TVM_RUNTIME_LINKER_LIBS})
 
+# Related headers
+target_include_directories(
+  tvm
+  PUBLIC "topi/include")
+target_include_directories(
+  tvm_objs
+  PUBLIC "topi/include")
+
+set(TVM_TEST_LIBRARY_NAME tvm)
 if (HIDE_PRIVATE_SYMBOLS AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
-  set(HIDE_SYMBOLS_LINKER_FLAGS "-Wl,--exclude-libs,ALL")
+  add_library(tvm_allvisible SHARED $<TARGET_OBJECTS:tvm_objs>)
+  target_include_directories(tvm_allvisible PUBLIC "$<TARGET_PROPERTY:tvm,INCLUDE_DIRECTORIES>")
+  target_link_libraries(tvm_allvisible PUBLIC "$<TARGET_PROPERTY:tvm,LINK_LIBRARIES>")
+  set(TVM_TEST_LIBRARY_NAME tvm_allvisible)
+
+set(HIDE_SYMBOLS_LINKER_FLAGS "-Wl,--exclude-libs,ALL")
   # Note: 'target_link_options' with 'PRIVATE' keyword would be cleaner
   # but it's not available until CMake 3.13. Switch to 'target_link_options'
   # once minimum CMake version is bumped up to 3.13 or above.
@@ -407,7 +426,7 @@ if(GTEST_INCLUDE_DIR AND GTEST_LIB)
     add_executable(${__execname} ${__srcpath})
     list(APPEND TEST_EXECS ${__execname})
     target_include_directories(${__execname} PUBLIC ${GTEST_INCLUDE_DIR})
-    target_link_libraries(${__execname} tvm ${GTEST_LIB} pthread dl)
+    target_link_libraries(${__execname} ${TVM_TEST_LIBRARY_NAME} ${GTEST_LIB} pthread dl)
     set_target_properties(${__execname} PROPERTIES EXCLUDE_FROM_ALL 1)
     set_target_properties(${__execname} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD 1)
   endforeach()
@@ -455,6 +474,6 @@ endif(INSTALL_DEV)
 
 # More target definitions
 if(MSVC)
-  target_compile_definitions(tvm PRIVATE -DTVM_EXPORTS)
-  target_compile_definitions(tvm_runtime PRIVATE -DTVM_EXPORTS)
+  target_compile_definitions(tvm_objs PRIVATE -DTVM_EXPORTS)
+  target_compile_definitions(tvm_runtime_objs PRIVATE -DTVM_EXPORTS)
 endif()
diff --git a/src/support/hexdump.cc b/src/support/hexdump.cc
new file mode 100644 (file)
index 0000000..6259815
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+/*!
+ *
+ * \file support/hexdump.cc
+ * \brief Print hex representation of BLOBs.
+ */
+
+#include "hexdump.h"
+
+namespace tvm {
+namespace support {
+
+void HexDump(const std::string& s, std::ostream& os) {
+  os << std::hex << std::setfill('0') << std::right;
+
+  int addr_width = 4;
+  for (size_t addr_bytes = s.size() >> 16; addr_bytes != 0; addr_bytes >>= 4) {
+    addr_width++;
+  }
+
+  for (size_t cursor = 0; cursor < s.size(); cursor += 0x10) {
+    os << std::setw(addr_width) << cursor;
+    size_t row_end = cursor + 0x10;
+    if (row_end > s.size()) {
+      row_end = s.size();
+    }
+
+    os << "  ";
+    for (size_t j = cursor; j < row_end; j++) {
+      os << " " << std::setw(2) << (unsigned int)(s[j] & 0xff);
+    }
+
+    for (size_t j = row_end; j < cursor + 0x10; j++) {
+      os << "   ";
+    }
+
+    os << std::setw(1) << "  ";
+    for (size_t j = cursor; j < row_end; j++) {
+      os << (isprint(s[j]) ? s[j] : '.');
+    }
+    os << std::endl;
+  }
+}
+
+}  // namespace support
+}  // namespace tvm
diff --git a/src/support/hexdump.h b/src/support/hexdump.h
new file mode 100644 (file)
index 0000000..4d660c6
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+/*!
+ *
+ * \file support/hexdump.h
+ * \brief Print hex representation of BLOBs.
+ */
+#ifndef TVM_SUPPORT_HEXDUMP_H_
+#define TVM_SUPPORT_HEXDUMP_H_
+
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+namespace tvm {
+namespace support {
+
+/*! \brief generate a hexdump of some binary data.
+ * \param s Binary data to print.
+ * \param os stream that receives the hexdump.
+ */
+void HexDump(const std::string& s, std::ostream& os);
+
+/*! \brief return a string containing a hexdump of the data in s */
+inline std::string HexDump(const std::string& s) {
+  std::stringstream ss;
+  HexDump(s, ss);
+  return ss.str();
+}
+
+}  // namespace support
+}  // namespace tvm
+#endif  // TVM_SUPPORT_HEXDUMP_H_
diff --git a/tests/cpp/support_test.cc b/tests/cpp/support_test.cc
new file mode 100644 (file)
index 0000000..bc9b944
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <dmlc/logging.h>
+#include <gtest/gtest.h>
+
+#include "../../src/support/hexdump.h"
+
+namespace tvm {
+namespace test {
+
+TEST(HexDumpTests, Empty) { EXPECT_EQ("", ::tvm::support::HexDump("")); }
+
+TEST(HexDumpTests, Aligned) {
+  EXPECT_EQ(
+      "0000   01 23 45 67 89 ab cd ef 01 23 45 67 89 ab cd ef  .#Eg.....#Eg....\n"
+      "0010   01 23 45 67 89 ab cd ef 01 23 45 67 89 ab cd ef  .#Eg.....#Eg....\n",
+      ::tvm::support::HexDump("\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
+                              "\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"));
+}
+
+TEST(HexDumpTests, Unaligned) {
+  EXPECT_EQ(
+      "0000   01 23 45 67 89 ab cd ef 01 23 45 67 89 ab cd ef  .#Eg.....#Eg....\n"
+      "0010   01 23 45 67 89 ab cd ef 01                       .#Eg.....\n",
+      ::tvm::support::HexDump("\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
+                              "\x01\x23\x45\x67\x89\xab\xcd\xef\x01"));
+}
+
+}  // namespace test
+}  // namespace tvm
+
+int main(int argc, char** argv) {
+  testing::InitGoogleTest(&argc, argv);
+  testing::FLAGS_gtest_death_test_style = "threadsafe";
+  return RUN_ALL_TESTS();
+}