diff --git a/BUILD b/BUILD.bazel similarity index 100% rename from BUILD rename to BUILD.bazel diff --git a/docs/development/how_to_debug.rst b/docs/development/how_to_debug.rst index ea4688585562d812d06cdfa4a27935f3252df66a..a28029da2d57d976883a98f16b9b99e38d70a97d 100644 --- a/docs/development/how_to_debug.rst +++ b/docs/development/how_to_debug.rst @@ -101,17 +101,22 @@ MACE also provides model visualization HTML generated in `builds` directory, gen Debug engine using log -------------------------- -Mace defines two sorts of logs: one is for users (LOG), the other is for developers (VLOG). +MACE implements a similar logging mechanism like `glog `__. +There are two types of logs, LOG for normal logging and VLOG for debugging. -LOG includes four levels, i.e, ``INFO``, ``WARNING``, ``ERROR``, ``FATAL``; -Environment variable ``MACE_CPP_MIN_LOG_LEVEL`` can be set to specify log level of users, e.g., -``set MACE_CPP_MIN_LOG_LEVEL=0`` will enable ``INFO`` log level, while ``set MACE_CPP_MIN_LOG_LEVEL=4`` will enable ``FATAL`` log level. +LOG includes four levels, sorted by severity level: ``INFO``, ``WARNING``, ``ERROR``, ``FATAL``. +The logging severity threshold can be configured via environment variable, e.g. ``MACE_CPP_MIN_LOG_LEVEL=WARNING`` to set as ``WARNING``. +Only the log messages with equal or above the specified severity threshold will be printed, the default threshold is ``INFO``. +We don't support integer log severity value like `glog `__, because they are confusing with VLOG. +VLOG is verbose logging which is logged as ``LOG(INFO)``. VLOG also has more detailed integer verbose levels, like 0, 1, 2, 3, etc. +The threshold can be configured through environment variable, e.g. ``MACE_CPP_MIN_VLOG_LEVEL=2`` to set as ``2``. +With VLOG, the lower the verbose level, the more likely messages are to be logged. For example, when the threshold is set +to 2, both ``VLOG(1)``, ``VLOG(2)`` log messages will be printed, but ``VLOG(3)`` and highers won't. -VLOG level is specified by numbers, e.g., 0, 1, 2. Environment variable ``MACE_CPP_MIN_VLOG_LEVEL`` can be set to specify vlog level. -Logs with higher levels than which is specified will be printed. So simply specifying a very large level number will make all logs printed. +All expensive logging with ``VLOG`` should be guarded with ``if(VLOG_IS_ON(lvl))`` check to avoid normal run overhead. -By using Mace run tool, vlog level can be easily set by option, e.g., +By using ``mace_run`` tool, VLOG level can be easily set by option, e.g., .. code:: sh @@ -168,9 +173,3 @@ things may be a little bit complicated. # then you can use it as host gdb, e.g., bt - - - - - - diff --git a/mace/BUILD b/mace/BUILD.bazel similarity index 86% rename from mace/BUILD rename to mace/BUILD.bazel index 4b7da51fccfac614fe845bdd95e58d960c62ed75..77e2c532ec7bb563a17af07e9fab1cfce27be58a 100644 --- a/mace/BUILD +++ b/mace/BUILD.bazel @@ -6,6 +6,22 @@ config_setting( visibility = ["//visibility:public"], ) +config_setting( + name = "linux", + define_values = { + "linux": "true", + }, + visibility = ["//visibility:public"], +) + +config_setting( + name = "darwin", + define_values = { + "darwin": "true", + }, + visibility = ["//visibility:public"], +) + config_setting( name = "android_armv7", values = { diff --git a/mace/benchmark/BUILD b/mace/benchmark/BUILD.bazel similarity index 100% rename from mace/benchmark/BUILD rename to mace/benchmark/BUILD.bazel diff --git a/mace/benchmark/benchmark_model.cc b/mace/benchmark/benchmark_model.cc index 666840e9fe31877d04b7197871775a7b3ed0f3c6..b0370321967f45f3698d83d446b32a63e1be2f39 100644 --- a/mace/benchmark/benchmark_model.cc +++ b/mace/benchmark/benchmark_model.cc @@ -23,7 +23,7 @@ #include "gflags/gflags.h" #include "mace/public/mace.h" #include "mace/utils/logging.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" #include "mace/benchmark/statistics.h" #ifdef MODEL_GRAPH_FORMAT_CODE #include "mace/codegen/engine/mace_engine_factory.h" diff --git a/mace/benchmark/model_throughput_test.cc b/mace/benchmark/model_throughput_test.cc index 66b178cf7178919adf57d064f2aa21ccee0dc491..cdc4639155cdab36f45eb038907e7ac71e069f2e 100644 --- a/mace/benchmark/model_throughput_test.cc +++ b/mace/benchmark/model_throughput_test.cc @@ -23,8 +23,7 @@ * --dsp_model_data_file=dsp_model_data.data \ * --run_seconds=10 */ -#include -#include +#include #include #include #include @@ -33,7 +32,7 @@ #include "gflags/gflags.h" #include "mace/public/mace.h" -#include "mace/utils/env_time.h" +#include "mace/port/env.h" #include "mace/utils/logging.h" #include "mace/core/types.h" diff --git a/mace/codegen/BUILD b/mace/codegen/BUILD.bazel similarity index 100% rename from mace/codegen/BUILD rename to mace/codegen/BUILD.bazel diff --git a/mace/core/BUILD b/mace/core/BUILD.bazel similarity index 96% rename from mace/core/BUILD rename to mace/core/BUILD.bazel index 2e37524ffd8a77e400ba2924cd656586744b3af3..14ddc6b6cfe215497d32b9a5509a3cc1835ea7a6 100644 --- a/mace/core/BUILD +++ b/mace/core/BUILD.bazel @@ -59,14 +59,12 @@ cc_library( ]) + if_neon_enabled([ "-DMACE_ENABLE_NEON", ]), - linkopts = ["-ldl"] + if_android([ - "-pie", - "-lm", - ]), + linkopts = ["-ldl"], deps = [ "//mace/codegen:generated_version", "//mace/proto:mace_cc", "//mace/utils", + "//mace/port", "@half//:half", ] + if_opencl_enabled([ ":opencl_headers", diff --git a/mace/core/allocator.h b/mace/core/allocator.h index 9c9103635245921ca2c354702b8ec9b062c40f37..c7499b92b51053436e61edabf4c93069c93f7a81 100644 --- a/mace/core/allocator.h +++ b/mace/core/allocator.h @@ -15,14 +15,13 @@ #ifndef MACE_CORE_ALLOCATOR_H_ #define MACE_CORE_ALLOCATOR_H_ -#include -#include +#include #include #include #include #include -#include "mace/core/macros.h" +#include "mace/utils/macros.h" #include "mace/core/types.h" #include "mace/core/runtime_failure_mock.h" #include "mace/public/mace.h" diff --git a/mace/core/buffer.h b/mace/core/buffer.h index ca7ada06f4c2d31eb497a968d842ccb2064a1937..418da27d95f01764659dde9515353d1d80ba4bca 100644 --- a/mace/core/buffer.h +++ b/mace/core/buffer.h @@ -21,8 +21,9 @@ #include #include "mace/core/allocator.h" -#include "mace/core/macros.h" #include "mace/core/types.h" +#include "mace/utils/logging.h" +#include "mace/utils/macros.h" namespace mace { namespace core { diff --git a/mace/core/future.h b/mace/core/future.h index 13382e1bf84575f2b0e5e63b0d881d720fc0e5d9..c7227d4df6ade05b1a6d392de0dbfa4772dff39d 100644 --- a/mace/core/future.h +++ b/mace/core/future.h @@ -20,11 +20,10 @@ #include #include "mace/utils/logging.h" +#include "mace/public/mace.h" namespace mace { -struct CallStats; - // Wait the call to finish and get the stats if param is not nullptr struct StatsFuture { std::function wait_fn = [](CallStats *stats) { diff --git a/mace/core/kv_storage.cc b/mace/core/kv_storage.cc index 5eba8567171bba82b6f2e9d2bef094b5614490e8..e2feb8c827b5939098eb0b7d3a451b1ad62b44a6 100644 --- a/mace/core/kv_storage.cc +++ b/mace/core/kv_storage.cc @@ -13,18 +13,18 @@ // limitations under the License. #include -#include #include #include #include +#include #include #include #include #include #include "mace/core/kv_storage.h" -#include "mace/core/macros.h" +#include "mace/utils/macros.h" #include "mace/utils/logging.h" namespace mace { diff --git a/mace/core/memory_optimizer.cc b/mace/core/memory_optimizer.cc index 0b448ac97c508cbc4786823d8318750db3e683d0..f2afdaa7de3e408b91a55aef46c97d4597e4ce26 100644 --- a/mace/core/memory_optimizer.cc +++ b/mace/core/memory_optimizer.cc @@ -21,8 +21,9 @@ #include #include "mace/core/arg_helper.h" -#include "mace/core/macros.h" +#include "mace/utils/macros.h" #include "mace/utils/logging.h" +#include "mace/public/mace.h" #ifdef MACE_ENABLE_OPENCL #include "mace/core/runtime/opencl/opencl_util.h" diff --git a/mace/core/net.cc b/mace/core/net.cc index 4bcbbb70e5378ff1dd76620e1dedcc61831dd48d..365bb353e6de3d5872e2ac75965183b403a09890 100644 --- a/mace/core/net.cc +++ b/mace/core/net.cc @@ -19,14 +19,16 @@ #include #include "mace/core/future.h" -#include "mace/core/macros.h" #include "mace/core/memory_optimizer.h" #include "mace/core/net.h" #include "mace/core/op_context.h" #include "mace/public/mace.h" -#include "mace/utils/memory_logging.h" +#include "mace/port/env.h" +#include "mace/utils/conf_util.h" +#include "mace/utils/logging.h" +#include "mace/utils/macros.h" +#include "mace/utils/math.h" #include "mace/utils/timer.h" -#include "mace/utils/utils.h" #ifdef MACE_ENABLE_OPENCL #include "mace/core/runtime/opencl/opencl_util.h" @@ -114,9 +116,8 @@ std::unique_ptr SerialNet::CreateOperation( } } } - std::unique_ptr op( - op_registry->CreateOperation(construct_context, device_type)); - return std::move(op); + + return op_registry->CreateOperation(construct_context, device_type); } SerialNet::SerialNet(const OpRegistryBase *op_registry, @@ -148,15 +149,14 @@ SerialNet::SerialNet(const OpRegistryBase *op_registry, continue; } for (int i = 0; i < op.output_size(); ++i) { - tensor_shape_map[op.output(i)] = - std::move(std::vector(op.output_shape(i).dims().begin(), - op.output_shape(i).dims().end())); + tensor_shape_map[op.output(i)] = std::vector( + op.output_shape(i).dims().begin(), + op.output_shape(i).dims().end()); } } for (auto &tensor : net_def->tensors()) { tensor_shape_map[tensor.name()] = - std::move(std::vector(tensor.dims().begin(), - tensor.dims().end())); + std::vector(tensor.dims().begin(), tensor.dims().end()); } bool has_data_format = false; @@ -468,7 +468,7 @@ MaceStatus SerialNet::Run(RunMetadata *run_metadata) { VLOG(3) << "Operator " << op->debug_def().name() << " has shape: " << MakeString(op->Output(0)->shape()); - if (EnvEnabled("MACE_LOG_TENSOR_RANGE")) { + if (EnvConfEnabled("MACE_LOG_TENSOR_RANGE")) { for (int i = 0; i < op->OutputSize(); ++i) { if (op->debug_def().quantize_info_size() == 0) { int data_type = op->GetOptionalArg("T", static_cast(DT_FLOAT)); diff --git a/mace/core/runtime/cpu/cpu_runtime.cc b/mace/core/runtime/cpu/cpu_runtime.cc index c4ed389265a9881fd6505476ffe45f5852f1bc15..34255e565460cd2958aabb80cfcd5b10ebc147e8 100644 --- a/mace/core/runtime/cpu/cpu_runtime.cc +++ b/mace/core/runtime/cpu/cpu_runtime.cc @@ -18,9 +18,6 @@ #include #endif -#include -#include -#include #include #include #include @@ -29,8 +26,9 @@ #include #include -#include "mace/core/macros.h" +#include "mace/port/env.h" #include "mace/public/mace.h" +#include "mace/utils/macros.h" #include "mace/utils/logging.h" namespace mace { @@ -44,86 +42,15 @@ struct CPUFreq { namespace { -int GetCPUCount() { - int cpu_count = 0; - std::string cpu_sys_conf = "/proc/cpuinfo"; - std::ifstream f(cpu_sys_conf); - if (!f.is_open()) { - LOG(ERROR) << "failed to open " << cpu_sys_conf; - return -1; - } - std::string line; - const std::string processor_key = "processor"; - while (std::getline(f, line)) { - if (line.size() >= processor_key.size() - && line.compare(0, processor_key.size(), processor_key) == 0) { - ++cpu_count; - } - } - if (f.bad()) { - LOG(ERROR) << "failed to read " << cpu_sys_conf; - } - if (!f.eof()) { - LOG(ERROR) << "failed to read end of " << cpu_sys_conf; - } - f.close(); - VLOG(2) << "CPU cores: " << cpu_count; - return cpu_count; -} - -int GetCPUMaxFreq(std::vector *max_freqs) { - int cpu_count = GetCPUCount(); - for (int cpu_id = 0; cpu_id < cpu_count; ++cpu_id) { - std::string cpuinfo_max_freq_sys_conf = MakeString( - "/sys/devices/system/cpu/cpu", - cpu_id, - "/cpufreq/cpuinfo_max_freq"); - std::ifstream f(cpuinfo_max_freq_sys_conf); - if (!f.is_open()) { - LOG(ERROR) << "failed to open " << cpuinfo_max_freq_sys_conf; - return -1; - } - std::string line; - if (std::getline(f, line)) { - float freq = strtof(line.c_str(), nullptr); - max_freqs->push_back(freq); - } - if (f.bad()) { - LOG(ERROR) << "failed to read " << cpuinfo_max_freq_sys_conf; - } - f.close(); - } - - for (float freq : *max_freqs) { - VLOG(2) << "CPU freq: " << freq; - } - - return 0; -} - -MaceStatus SetThreadAffinity(cpu_set_t mask) { -#if defined(__ANDROID__) - pid_t pid = gettid(); -#else - pid_t pid = syscall(SYS_gettid); -#endif - int err = sched_setaffinity(pid, sizeof(mask), &mask); - if (err) { - LOG(WARNING) << "set affinity error: " << strerror(errno); - return MaceStatus(MaceStatus::MACE_INVALID_ARGS, - "set affinity error: " + std::string(strerror(errno))); - } else { - return MaceStatus::MACE_SUCCESS; - } -} - MaceStatus SetOpenMPThreadsAndAffinityCPUs(int omp_num_threads, const std::vector &cpu_ids) { MaceOpenMPThreadCount = omp_num_threads; #ifdef MACE_ENABLE_OPENMP - VLOG(1) << "Set OpenMP threads number: " << omp_num_threads - << ", CPU core IDs: " << MakeString(cpu_ids); + if (VLOG_IS_ON(1)) { + VLOG(1) << "Set OpenMP threads number: " << omp_num_threads + << ", CPU core IDs: " << MakeString(cpu_ids); + } omp_set_schedule(omp_sched_guided, 1); omp_set_num_threads(omp_num_threads); #else @@ -131,12 +58,6 @@ MaceStatus SetOpenMPThreadsAndAffinityCPUs(int omp_num_threads, LOG(WARNING) << "Set OpenMP threads number failed: OpenMP not enabled."; #endif - // compute mask - cpu_set_t mask; - CPU_ZERO(&mask); - for (auto cpu_id : cpu_ids) { - CPU_SET(cpu_id, &mask); - } #ifdef MACE_ENABLE_OPENMP std::vector status(omp_num_threads, MaceStatus::MACE_INVALID_ARGS); @@ -144,7 +65,7 @@ MaceStatus SetOpenMPThreadsAndAffinityCPUs(int omp_num_threads, for (int i = 0; i < omp_num_threads; ++i) { VLOG(1) << "Set affinity for OpenMP thread " << omp_get_thread_num() << "/" << omp_get_num_threads(); - status[i] = SetThreadAffinity(mask); + status[i] = SchedSetAffinity(cpu_ids); } for (int i = 0; i < omp_num_threads; ++i) { if (status[i] != MaceStatus::MACE_SUCCESS) @@ -152,8 +73,10 @@ MaceStatus SetOpenMPThreadsAndAffinityCPUs(int omp_num_threads, } return MaceStatus::MACE_SUCCESS; #else - MaceStatus status = SetThreadAffinity(mask); - VLOG(1) << "Set affinity without OpenMP: " << mask.__bits[0]; + MaceStatus status = SchedSetAffinity(cpu_ids); + if (VLOG_IS_ON(1)) { + VLOG(1) << "Set affinity without OpenMP: " << MakeString(cpu_ids); + } return status; #endif } @@ -166,8 +89,9 @@ MaceStatus CPURuntime::SetOpenMPThreadsAndAffinityPolicy( void *gemm_context) { // get cpu frequency info std::vector cpu_max_freqs; - if (GetCPUMaxFreq(&cpu_max_freqs) == -1 || cpu_max_freqs.size() == 0) { - return MaceStatus::MACE_INVALID_ARGS; + MACE_RETURN_IF_ERROR(GetCpuMaxFreq(&cpu_max_freqs)); + if (cpu_max_freqs.empty()) { + return MaceStatus::MACE_RUNTIME_ERROR; } std::vector cpu_freq(cpu_max_freqs.size()); diff --git a/mace/core/runtime/cpu/cpu_runtime.h b/mace/core/runtime/cpu/cpu_runtime.h index 95fee27f5424eeed2f29eb782bd085115ab430c9..bb97267f67f46f1bb47b1729d162985b055418f7 100644 --- a/mace/core/runtime/cpu/cpu_runtime.h +++ b/mace/core/runtime/cpu/cpu_runtime.h @@ -22,7 +22,7 @@ #include "public/gemmlowp.h" #endif // MACE_ENABLE_QUANTIZE -#include "mace/core/macros.h" +#include "mace/utils/macros.h" #include "mace/public/mace.h" #include "mace/utils/logging.h" diff --git a/mace/core/runtime/hexagon/hexagon_control_wrapper.cc b/mace/core/runtime/hexagon/hexagon_control_wrapper.cc index e19d98c7805c5037f621e60469f5600118663d05..b39bfeed2510ab10f401fe653ac3ad919e8b2619 100644 --- a/mace/core/runtime/hexagon/hexagon_control_wrapper.cc +++ b/mace/core/runtime/hexagon/hexagon_control_wrapper.cc @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include #include #include #include // NOLINT(build/c++11) @@ -24,16 +23,9 @@ #include "mace/core/runtime/hexagon/hexagon_control_wrapper.h" #include "mace/core/runtime/hexagon/hexagon_nn_ops.h" #include "mace/core/types.h" +#include "mace/port/env.h" #include "mace/utils/quantize.h" -namespace { -inline int64_t NowMicros() { - struct timeval tv; - gettimeofday(&tv, nullptr); - return static_cast(tv.tv_sec) * 1000000 + tv.tv_usec; -} -} - namespace mace { #define MACE_MAX_NODE 2048 diff --git a/mace/core/runtime/opencl/opencl_runtime.cc b/mace/core/runtime/opencl/opencl_runtime.cc index 31cd5a541ee809d53f065e9ef63c67d819963c5f..0a5f9460f1026670224dfa28738cca15486a206e 100644 --- a/mace/core/runtime/opencl/opencl_runtime.cc +++ b/mace/core/runtime/opencl/opencl_runtime.cc @@ -24,7 +24,7 @@ #include #include -#include "mace/core/macros.h" +#include "mace/utils/macros.h" #include "mace/core/kv_storage.h" #include "mace/core/runtime/opencl/opencl_extension.h" #include "mace/utils/tuner.h" @@ -273,7 +273,7 @@ OpenCLRuntime::OpenCLRuntime( gpu_type_(UNKNOWN) { std::vector all_platforms; cl::Platform::get(&all_platforms); - if (all_platforms.size() == 0) { + if (all_platforms.empty()) { LOG(ERROR) << "No OpenCL platforms found"; return; } @@ -289,7 +289,7 @@ OpenCLRuntime::OpenCLRuntime( // get default device (CPUs, GPUs) of the default platform std::vector all_devices; default_platform.getDevices(CL_DEVICE_TYPE_ALL, &all_devices); - if (all_devices.size() == 0) { + if (all_devices.empty()) { LOG(ERROR) << "No OpenCL devices found"; return; } diff --git a/mace/core/runtime/opencl/opencl_util.cc b/mace/core/runtime/opencl/opencl_util.cc index ff409e571bab3d92febd5cd8918c9ca4072d40cb..7aecf6f115fd8d327c5c793cba2986553ded4061 100644 --- a/mace/core/runtime/opencl/opencl_util.cc +++ b/mace/core/runtime/opencl/opencl_util.cc @@ -17,6 +17,7 @@ #include #include "mace/utils/logging.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/core/testing/test_benchmark.cc b/mace/core/testing/test_benchmark.cc index 03442869230066d081bef599d74d277283d386f0..a7cd149579bc6d6bf875a7b993010d6243a4d49a 100644 --- a/mace/core/testing/test_benchmark.cc +++ b/mace/core/testing/test_benchmark.cc @@ -20,7 +20,7 @@ #include #include "mace/core/testing/test_benchmark.h" -#include "mace/utils/env_time.h" +#include "mace/port/env.h" #include "mace/utils/logging.h" namespace mace { diff --git a/mace/examples/cli/BUILD b/mace/examples/cli/BUILD.bazel similarity index 100% rename from mace/examples/cli/BUILD rename to mace/examples/cli/BUILD.bazel diff --git a/mace/libmace/BUILD b/mace/libmace/BUILD.bazel similarity index 67% rename from mace/libmace/BUILD rename to mace/libmace/BUILD.bazel index 1cecc7f60f86ca15904d40eb57188a2e42a83006..2dba327be5edb4623f8b2ff61a2b25c245b2e1a4 100644 --- a/mace/libmace/BUILD +++ b/mace/libmace/BUILD.bazel @@ -10,13 +10,13 @@ licenses(["notice"]) # Apache 2.0 load( "//mace:mace.bzl", "if_android", + "if_linux", + "if_darwin", "if_neon_enabled", - "if_neon_enabled_str", "if_openmp_enabled", "if_android_armv7", "if_hexagon_enabled", "if_opencl_enabled", - "if_opencl_enabled_str", "if_quantize_enabled", ) @@ -77,6 +77,7 @@ cc_library( visibility = ["//visibility:public"], ) +# For details, see https://github.com/bazelbuild/bazel/issues/5200 genrule( name = "libmace_static", srcs = [ @@ -87,10 +88,18 @@ genrule( "//mace/ops:internal_ops", "//mace/ops", "//mace/libmace", + "//mace/port:port_base", + "//mace/port/posix:port_posix", "//mace/utils", "//mace/proto:mace_cc", "@com_google_protobuf//:protobuf_lite", - ] + if_opencl_enabled([ + ] + if_android([ + "//mace/port/android:port_android", + ]) + if_linux([ + "//mace/port/linux:port_linux", + ]) + if_darwin([ + "//mace/port/darwin:port_darwin", + ]) + if_opencl_enabled([ "//mace/ops:opencl_kernels", "//mace/codegen:generated_opencl", ]) + if_neon_enabled([ @@ -103,20 +112,43 @@ genrule( "$(locations //mace/core:core) " + "$(locations //mace/ops:common) " + "$(locations //mace/ops:ref_kernels) " + - if_neon_enabled_str("$(locations //mace/ops:arm_neon_kernels) ") + - if_opencl_enabled_str("$(locations //mace/ops:opencl_kernels) ") + + if_neon_enabled( + "$(locations //mace/ops:arm_neon_kernels) ", + default_value = "", + ) + + if_opencl_enabled( + "$(locations //mace/ops:opencl_kernels) ", + default_value = "", + ) + "$(locations //mace/ops:internal_ops) " + "$(locations //mace/ops:ops) " + "$(locations //mace/libmace:libmace) " + + "$(locations //mace/port:port_base) " + + "$(locations //mace/port/posix:port_posix) " + + if_android( + "$(locations //mace/port/android:port_android) ", + default_value = "", + ) + + if_linux( + "$(locations //mace/port/linux:port_linux) ", + default_value = "", + ) + + if_darwin( + "$(locations //mace/port/darwin:port_darwin) ", + default_value = "", + ) + "$(locations //mace/utils:utils) " + "$(locations //mace/proto:mace_cc) " + "$(locations @com_google_protobuf//:protobuf_lite) " + - if_opencl_enabled_str("$(locations //mace/codegen:generated_opencl) ") + + if_opencl_enabled( + "$(locations //mace/codegen:generated_opencl) ", + default_value = "", + ) + "$@ " + "$$tmp_mri_file);" + "$(AR) -M <$$tmp_mri_file;" + - "rm -rf $$tmp_mri_file;" + - "$(STRIP) -x $@;", + "rm -rf $$tmp_mri_file;", + # "$(STRIP) -x $@;", # FIXME this will crash tools = ["//mace/python/tools:archive_static_lib"], visibility = ["//visibility:public"], ) diff --git a/mace/libmace/mace.cc b/mace/libmace/mace.cc index 2d0acb450aadf9d60b285e4fb71a748c1870fa4f..78991a71c74f206abdfe4cf8d547b2fd6d6b2826 100644 --- a/mace/libmace/mace.cc +++ b/mace/libmace/mace.cc @@ -21,7 +21,12 @@ #include "mace/core/net.h" #include "mace/ops/ops_registry.h" #include "mace/ops/common/transpose.h" +#include "mace/utils/math.h" +#include "mace/utils/memory.h" +#include "mace/utils/stl_util.h" #include "mace/public/mace.h" +#include "mace/port/env.h" +#include "mace/port/file_system.h" #ifdef MACE_ENABLE_OPENCL #include "mace/core/runtime/opencl/gpu_device.h" @@ -33,8 +38,6 @@ #include "mace/core/runtime/hexagon/hexagon_device.h" #endif // MACE_ENABLE_HEXAGON -#include "mace/utils/memory.h" - namespace mace { namespace { @@ -377,8 +380,7 @@ class MaceEngine::Impl { std::pair *output); private: - const unsigned char *model_data_; - size_t model_data_size_; + std::unique_ptr model_data_; std::unique_ptr op_registry_; DeviceType device_type_; std::unique_ptr device_; @@ -396,7 +398,6 @@ class MaceEngine::Impl { MaceEngine::Impl::Impl(const MaceEngineConfig &config) : model_data_(nullptr), - model_data_size_(0), op_registry_(new OpRegistry), device_type_(config.impl_->device_type()), device_(nullptr), @@ -490,7 +491,7 @@ MaceStatus MaceEngine::Impl::Init( MACE_CHECK(hexagon_controller_->Config(), "hexagon config error"); MACE_CHECK(hexagon_controller_->Init(), "hexagon init error"); hexagon_controller_->SetDebugLevel( - static_cast(mace::logging::LogMessage::MinVLogLevel())); + static_cast(mace::port::MinVLogLevelFromEnv())); MACE_CHECK(hexagon_controller_->SetupGraph(*net_def, model_data), "hexagon setup graph error"); if (VLOG_IS_ON(2)) { @@ -532,23 +533,22 @@ MaceStatus MaceEngine::Impl::Init( const std::string &model_data_file) { LOG(INFO) << "Loading Model Data"; - MemoryMap(model_data_file, &model_data_, &model_data_size_); + auto fs = GetFileSystem(); + MACE_RETURN_IF_ERROR(fs->NewReadOnlyMemoryRegionFromFile( + model_data_file.c_str(), &model_data_)); - MACE_RETURN_IF_ERROR(Init(net_def, input_nodes, output_nodes, model_data_)); + MACE_RETURN_IF_ERROR(Init(net_def, input_nodes, output_nodes, + reinterpret_cast(model_data_->data()))); if (device_type_ == DeviceType::GPU || device_type_ == DeviceType::HEXAGON || (device_type_ == DeviceType::CPU && ws_->diffused_buffer())) { - MemoryUnMap(model_data_, model_data_size_); - model_data_ = nullptr; + model_data_.reset(); } return MaceStatus::MACE_SUCCESS; } MaceEngine::Impl::~Impl() { LOG(INFO) << "Destroying MaceEngine"; - if (model_data_ != nullptr) { - MemoryUnMap(model_data_, model_data_size_); - } #ifdef MACE_ENABLE_HEXAGON if (device_type_ == HEXAGON) { if (VLOG_IS_ON(2)) { diff --git a/mace/mace.bzl b/mace/mace.bzl index 2afe4560e323d2ad1cbe731832c5a918b09b177b..ee9f8c59dc94ab15dd0749205c4630ce9f4b1ce4 100644 --- a/mace/mace.bzl +++ b/mace/mace.bzl @@ -1,15 +1,21 @@ # -*- Python -*- -def if_android(a): +def if_android(a, default_value = []): return select({ "//mace:android": a, - "//conditions:default": [], + "//conditions:default": default_value, }) -def if_not_android(a): +def if_linux(a, default_value = []): return select({ - "//mace:android": [], - "//conditions:default": a, + "//mace:linux": a, + "//conditions:default": default_value, + }) + +def if_darwin(a, default_value = []): + return select({ + "//mace:darwin": a, + "//conditions:default": default_value, }) def if_android_armv7(a): @@ -36,16 +42,10 @@ def if_arm_linux_armhf(a): "//conditions:default": [] }) -def if_neon_enabled(a): +def if_neon_enabled(a, default_value = []): return select({ "//mace:neon_enabled": a, - "//conditions:default": [], - }) - -def if_neon_enabled_str(a): - return select({ - "//mace:neon_enabled": a, - "//conditions:default": "", + "//conditions:default": default_value, }) def if_hexagon_enabled(a): @@ -66,16 +66,10 @@ def if_openmp_enabled(a): "//conditions:default": [], }) -def if_opencl_enabled(a): - return select({ - "//mace:opencl_enabled": a, - "//conditions:default": [], - }) - -def if_opencl_enabled_str(a): +def if_opencl_enabled(a, default_value = []): return select({ "//mace:opencl_enabled": a, - "//conditions:default": "", + "//conditions:default": default_value, }) def if_quantize_enabled(a): diff --git a/mace/ops/BUILD b/mace/ops/BUILD.bazel similarity index 95% rename from mace/ops/BUILD rename to mace/ops/BUILD.bazel index aa434203db3da0eeb6be83c3e0538b3b76551fbe..bbf5f34822b734eb6555702cc219454bcf4ec051 100644 --- a/mace/ops/BUILD +++ b/mace/ops/BUILD.bazel @@ -54,34 +54,14 @@ cc_library( cc_library( name = "testing", - srcs = glob( - [ - "testing/*.cc", - ], - ), - hdrs = glob( - [ - "testing/*.h", - ], - ), + hdrs = [ + "testing/test_utils.h", + ], copts = [ "-Werror", "-Wextra", "-Wno-missing-field-initializers", - ] + if_openmp_enabled([ - "-fopenmp", - ]) + if_neon_enabled([ - "-DMACE_ENABLE_NEON", - ]) + if_android_armv7([ - "-mfpu=neon", - "-mfloat-abi=softfp", - ]) + if_opencl_enabled([ - "-DMACE_ENABLE_OPENCL", - ]) + if_quantize_enabled([ - "-DMACE_ENABLE_QUANTIZE", - ]) + if_hexagon_enabled([ - "-DMACE_ENABLE_HEXAGON", - ]), + ], deps = [ "//mace/core", "@gtest", diff --git a/mace/ops/arm/conv_2d_neon_15x1.cc b/mace/ops/arm/conv_2d_neon_15x1.cc index 8523e494cebf92e359b0d53c9a3e2a7ab8cc2fcb..5cd58fcca5f9348cdfb1062c4864ed7ad65fb02c 100644 --- a/mace/ops/arm/conv_2d_neon_15x1.cc +++ b/mace/ops/arm/conv_2d_neon_15x1.cc @@ -17,7 +17,7 @@ #endif #include "mace/ops/arm/conv_2d_neon.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { namespace ops { diff --git a/mace/ops/arm/conv_2d_neon_1x15.cc b/mace/ops/arm/conv_2d_neon_1x15.cc index 33b9abbfebc2c921423b15288012487038d2b370..b8837490da72d003b4458853045adea5cd51bac6 100644 --- a/mace/ops/arm/conv_2d_neon_1x15.cc +++ b/mace/ops/arm/conv_2d_neon_1x15.cc @@ -18,7 +18,7 @@ #include "mace/ops/arm/conv_2d_neon.h" #include "mace/utils/logging.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { namespace ops { diff --git a/mace/ops/arm/conv_2d_neon_3x3.cc b/mace/ops/arm/conv_2d_neon_3x3.cc index ecae6810696d07d82d688a183720c7acb3243f8d..3555b4a57078433c47c8d8ba34b60a649367b617 100644 --- a/mace/ops/arm/conv_2d_neon_3x3.cc +++ b/mace/ops/arm/conv_2d_neon_3x3.cc @@ -16,7 +16,7 @@ #include #endif -#include "mace/core/macros.h" +#include "mace/utils/macros.h" #include "mace/ops/arm/conv_2d_neon.h" namespace mace { diff --git a/mace/ops/arm/deconv_2d_neon_2x2.cc b/mace/ops/arm/deconv_2d_neon_2x2.cc index 74ddbecc48c367c07692e43b6260ece23aee6abb..a1bd1883e380d57bf17da2ac07af25963921dfdf 100644 --- a/mace/ops/arm/deconv_2d_neon_2x2.cc +++ b/mace/ops/arm/deconv_2d_neon_2x2.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "mace/core/macros.h" +#include "mace/utils/macros.h" #include "mace/ops/arm/deconv_2d_neon.h" namespace mace { diff --git a/mace/ops/arm/deconv_2d_neon_3x3.cc b/mace/ops/arm/deconv_2d_neon_3x3.cc index 356680949af572838a070c47f91a69427751d596..2859b7c04bcc68e4c6454a63aa7969132cc0fb7f 100644 --- a/mace/ops/arm/deconv_2d_neon_3x3.cc +++ b/mace/ops/arm/deconv_2d_neon_3x3.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "mace/core/macros.h" +#include "mace/utils/macros.h" #include "mace/ops/arm/deconv_2d_neon.h" namespace mace { diff --git a/mace/ops/arm/deconv_2d_neon_4x4.cc b/mace/ops/arm/deconv_2d_neon_4x4.cc index a023154aec04c94ff4dcc77767999522a87a0368..690bea4ed99d6823d162db2cc068e26b220ea339 100644 --- a/mace/ops/arm/deconv_2d_neon_4x4.cc +++ b/mace/ops/arm/deconv_2d_neon_4x4.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "mace/core/macros.h" +#include "mace/utils/macros.h" #include "mace/ops/arm/deconv_2d_neon.h" namespace mace { diff --git a/mace/ops/arm/depthwise_conv2d_neon_3x3.cc b/mace/ops/arm/depthwise_conv2d_neon_3x3.cc index 652d0231bdc60c6f3b53c65b3a94131e7de47d15..9d6ae41e16e2c0a8a525cfbd47a9662583f84e8d 100644 --- a/mace/ops/arm/depthwise_conv2d_neon_3x3.cc +++ b/mace/ops/arm/depthwise_conv2d_neon_3x3.cc @@ -16,7 +16,7 @@ #include #endif -#include "mace/core/macros.h" +#include "mace/utils/macros.h" #include "mace/ops/arm/depthwise_conv2d_neon.h" namespace mace { diff --git a/mace/ops/arm/depthwise_deconv2d_neon_3x3.cc b/mace/ops/arm/depthwise_deconv2d_neon_3x3.cc index 404c903d30d0ca30695c94d889f9346764967c64..a666961b39186151ceb2af2c8a729e637f00f04d 100644 --- a/mace/ops/arm/depthwise_deconv2d_neon_3x3.cc +++ b/mace/ops/arm/depthwise_deconv2d_neon_3x3.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "mace/core/macros.h" +#include "mace/utils/macros.h" #include "mace/ops/arm/depthwise_deconv2d_neon.h" namespace mace { diff --git a/mace/ops/arm/depthwise_deconv2d_neon_4x4.cc b/mace/ops/arm/depthwise_deconv2d_neon_4x4.cc index 1b59264e600c064f76dddfbcf3b6b4ec83d535a2..a7c10b8601bb6783096d466f003e2ba4d4550184 100644 --- a/mace/ops/arm/depthwise_deconv2d_neon_4x4.cc +++ b/mace/ops/arm/depthwise_deconv2d_neon_4x4.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "mace/core/macros.h" +#include "mace/utils/macros.h" #include "mace/ops/arm/deconv_2d_neon.h" namespace mace { diff --git a/mace/ops/arm/fp32/conv_2d_3x3_winograd.cc b/mace/ops/arm/fp32/conv_2d_3x3_winograd.cc index 12655eacd9b170355a2f560e0c0f0979b13863f4..84f12125649fce6c701356d9a9395383efd463b2 100644 --- a/mace/ops/arm/fp32/conv_2d_3x3_winograd.cc +++ b/mace/ops/arm/fp32/conv_2d_3x3_winograd.cc @@ -16,6 +16,8 @@ #include "mace/ops/arm/fp32/conv_2d_3x3_winograd.h" #include "mace/ops/common/conv_pool_2d_util.h" +#include "mace/utils/memory.h" +#include "mace/utils/math.h" namespace mace { namespace ops { diff --git a/mace/ops/arm/fp32/gemm.h b/mace/ops/arm/fp32/gemm.h index f4cfc42bb199161a877ab0329670004ef94a6b97..36eb0378b9853c9a6145bfc5a2d1b0ada9afbc44 100644 --- a/mace/ops/arm/fp32/gemm.h +++ b/mace/ops/arm/fp32/gemm.h @@ -19,6 +19,7 @@ #include "mace/core/tensor.h" #include "mace/core/op_context.h" #include "mace/ops/common/matrix.h" +#include "mace/utils/math.h" // This implements matrix-matrix multiplication. // In the case of matrix-vector multiplication, use gemv.h/gemv.cc instead diff --git a/mace/ops/arm/fp32/gemv.cc b/mace/ops/arm/fp32/gemv.cc index 89474fbb16965f262dba50b7c26542cabdf61511..cd0f607fd63f16bb5c99ea0a369dc8423a6bf358 100644 --- a/mace/ops/arm/fp32/gemv.cc +++ b/mace/ops/arm/fp32/gemv.cc @@ -18,6 +18,8 @@ #include #include +#include "mace/utils/math.h" + #if !defined(__aarch64__) float vaddvq_f32(float32x4_t v) { float32x2_t _sum = vadd_f32(vget_low_f32(v), vget_high_f32(v)); diff --git a/mace/ops/arm/q8/gemv.cc b/mace/ops/arm/q8/gemv.cc index d52ed48d65a2b8683dd68c88ba88ee84d82c660d..ce102e7e3171ff3344b4535576c9187866305fcd 100644 --- a/mace/ops/arm/q8/gemv.cc +++ b/mace/ops/arm/q8/gemv.cc @@ -18,7 +18,7 @@ #include #include -#include "mace/utils/utils.h" +#include "mace/utils/math.h" #include "mace/utils/quantize.h" #if !defined(__aarch64__) diff --git a/mace/ops/batch_norm_benchmark.cc b/mace/ops/batch_norm_benchmark.cc index 11bf4f6e74dbfd7141963add244c50f8b9b1ff35..74f7a013c14af8294aaabcddf5a7a29d8662edf1 100644 --- a/mace/ops/batch_norm_benchmark.cc +++ b/mace/ops/batch_norm_benchmark.cc @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "mace/core/runtime/opencl/opencl_runtime.h" #include "mace/core/testing/test_benchmark.h" #include "mace/ops/ops_test_util.h" diff --git a/mace/ops/conv_2d.cc b/mace/ops/conv_2d.cc index 4d54effae7899291a69e97ff25dc2b5f0f3b6b8c..65a723ad649be63332513ad69e989edc9b675368 100644 --- a/mace/ops/conv_2d.cc +++ b/mace/ops/conv_2d.cc @@ -31,7 +31,7 @@ #include "mace/ops/conv_pool_2d_base.h" #include "mace/ops/common/conv_pool_2d_util.h" #include "mace/utils/memory.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" #ifdef MACE_ENABLE_NEON #include "mace/ops/arm/fp32/conv_2d.h" diff --git a/mace/ops/deconv_2d.cc b/mace/ops/deconv_2d.cc index 3585659f5229e3f315e0a415d78dade8915beea2..6e9a0fa8db36209887f86d0fdc75d5c5d1a5c2bc 100644 --- a/mace/ops/deconv_2d.cc +++ b/mace/ops/deconv_2d.cc @@ -29,7 +29,7 @@ #include "mace/ops/activation.h" #include "mace/ops/arm/deconv_2d_neon.h" #include "mace/utils/memory.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" #ifdef MACE_ENABLE_OPENCL #include "mace/ops/opencl/buffer_transformer.h" #include "mace/ops/opencl/image/deconv_2d.h" diff --git a/mace/ops/depthwise_deconv2d.cc b/mace/ops/depthwise_deconv2d.cc index a2d188a96a78bcc51ba4d48312d8ab3b155f3721..3d203cfa5678c1ca407b6db2d441890bc00785a5 100644 --- a/mace/ops/depthwise_deconv2d.cc +++ b/mace/ops/depthwise_deconv2d.cc @@ -26,7 +26,7 @@ #include "mace/core/future.h" #include "mace/core/tensor.h" #include "mace/ops/arm/depthwise_deconv2d_neon.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" #include "mace/public/mace.h" #include "mace/utils/memory.h" #ifdef MACE_ENABLE_OPENCL diff --git a/mace/ops/matmul.cc b/mace/ops/matmul.cc index 3c971b6f9921d9ab737c719685a3d85967a8da2f..3b0913de574607660b807ea133f3e797a30aca71 100644 --- a/mace/ops/matmul.cc +++ b/mace/ops/matmul.cc @@ -21,7 +21,7 @@ #include "mace/core/operator.h" #include "mace/core/tensor.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" #ifdef MACE_ENABLE_NEON #include "mace/ops/arm/fp32/gemm.h" diff --git a/mace/ops/opencl/activation.h b/mace/ops/opencl/activation.h index 6eecb6416659f899e4926332a02695597782ee62..6e9b92242b499906fb3304fdcedfc1e739e9abb4 100644 --- a/mace/ops/opencl/activation.h +++ b/mace/ops/opencl/activation.h @@ -16,7 +16,7 @@ #define MACE_OPS_OPENCL_ACTIVATION_H_ #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/addn.h b/mace/ops/opencl/addn.h index b78a7099646f77f40e5f2c058d90dcd414cb0dec..ba161ba641ed6d1c041e2e41aa547f1c45071e48 100644 --- a/mace/ops/opencl/addn.h +++ b/mace/ops/opencl/addn.h @@ -18,7 +18,7 @@ #include #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/batch_norm.h b/mace/ops/opencl/batch_norm.h index 6f91f95d67d4efe23ae9b8eb57142ea7ba1f3acd..bf49c994e127910632dfd2b2ce9d76a4855a29dc 100644 --- a/mace/ops/opencl/batch_norm.h +++ b/mace/ops/opencl/batch_norm.h @@ -16,7 +16,7 @@ #define MACE_OPS_OPENCL_BATCH_NORM_H_ #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/batch_to_space.h b/mace/ops/opencl/batch_to_space.h index 4cf8db94399d13ed77391d80f8d7447b8edff59a..9bb62f7052d64ba437d44f5d0ed6403c475c3dde 100644 --- a/mace/ops/opencl/batch_to_space.h +++ b/mace/ops/opencl/batch_to_space.h @@ -19,7 +19,7 @@ #include "mace/core/types.h" #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/bias_add.h b/mace/ops/opencl/bias_add.h index d0b4469dd0154ae7234f984771ffa70509abeb32..80a86423c50922bec581b445206445cf2df83d41 100644 --- a/mace/ops/opencl/bias_add.h +++ b/mace/ops/opencl/bias_add.h @@ -16,7 +16,7 @@ #define MACE_OPS_OPENCL_BIAS_ADD_H_ #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/buffer_transform_kernel.h b/mace/ops/opencl/buffer_transform_kernel.h index 4269b67d22ca157f28fcde4a0f607f9ae6e9a5df..47f1cbaf10f4cf70c0a1d9014ba0ad77261414fe 100644 --- a/mace/ops/opencl/buffer_transform_kernel.h +++ b/mace/ops/opencl/buffer_transform_kernel.h @@ -17,7 +17,7 @@ #include "mace/core/runtime/opencl/opencl_util.h" #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { class OpContext; diff --git a/mace/ops/opencl/channel_shuffle.h b/mace/ops/opencl/channel_shuffle.h index 86634d75bc0bb0e13254ec0a9c82714f7b746fda..df4a4b0f8e7fd92a0e4663643aeb1ef66de04e79 100644 --- a/mace/ops/opencl/channel_shuffle.h +++ b/mace/ops/opencl/channel_shuffle.h @@ -16,7 +16,7 @@ #define MACE_OPS_OPENCL_CHANNEL_SHUFFLE_H_ #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/concat.h b/mace/ops/opencl/concat.h index d657ffbe9bdd2f69301b9f519491433531822f8d..abeec7c62e25299ac4de95e0b0dadc61bdb35900 100644 --- a/mace/ops/opencl/concat.h +++ b/mace/ops/opencl/concat.h @@ -18,7 +18,7 @@ #include #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/crop.h b/mace/ops/opencl/crop.h index 88aceea6f93845ece318b8b26b45e25eaf24dbfc..b12c5ee00fed43c0f954921bac11a26fa21e0f7e 100644 --- a/mace/ops/opencl/crop.h +++ b/mace/ops/opencl/crop.h @@ -18,7 +18,7 @@ #include #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/depth_to_space.h b/mace/ops/opencl/depth_to_space.h index 17c03d453593ccb7ca1c1ae58890f80b01a5c706..9d2d4fcba65fe01545c2588cdb9d667f53408af7 100644 --- a/mace/ops/opencl/depth_to_space.h +++ b/mace/ops/opencl/depth_to_space.h @@ -16,7 +16,7 @@ #define MACE_OPS_OPENCL_DEPTH_TO_SPACE_H_ #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { class OpContext; diff --git a/mace/ops/opencl/eltwise.h b/mace/ops/opencl/eltwise.h index dec2b150d79a372a05895482a7db1819766b20e5..52156f06e908a394ae910abbeefb6da23e6cb236 100644 --- a/mace/ops/opencl/eltwise.h +++ b/mace/ops/opencl/eltwise.h @@ -16,7 +16,7 @@ #define MACE_OPS_OPENCL_ELTWISE_H_ #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/fully_connected.h b/mace/ops/opencl/fully_connected.h index 8e421ad2f20510a76dcc0c5c841745d1832ac688..416aed6c8692ceaf45da1d1eb36f82b3753c8729 100644 --- a/mace/ops/opencl/fully_connected.h +++ b/mace/ops/opencl/fully_connected.h @@ -18,7 +18,7 @@ #include "mace/ops/activation.h" #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/helper.cc b/mace/ops/opencl/helper.cc index a801e91048efaca60e08f52e36367aa09cbee317..912a8d8d87e549290cf5d174187d288c2462fcb1 100644 --- a/mace/ops/opencl/helper.cc +++ b/mace/ops/opencl/helper.cc @@ -19,7 +19,7 @@ #include #include "mace/utils/tuner.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { namespace ops { diff --git a/mace/ops/opencl/helper.h b/mace/ops/opencl/helper.h index cf3beeac9d304b6530c29c395979527b33cc326c..a4a49b4e15a021f1fa55fbd39c514777f03005bd 100644 --- a/mace/ops/opencl/helper.h +++ b/mace/ops/opencl/helper.h @@ -21,13 +21,13 @@ #include #include "mace/core/future.h" -#include "mace/core/macros.h" +#include "mace/utils/macros.h" #include "mace/core/runtime/opencl/cl2_header.h" #include "mace/core/runtime/opencl/opencl_runtime.h" #include "mace/core/runtime/opencl/opencl_util.h" #include "mace/core/types.h" #include "mace/utils/memory.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { namespace ops { diff --git a/mace/ops/opencl/image/conv_2d_3x3.cc b/mace/ops/opencl/image/conv_2d_3x3.cc index db63300eb7607dead1cc9661533e0e7d463e5e4b..125a973ae7de4409b31fa2a716c35409d5955d0e 100644 --- a/mace/ops/opencl/image/conv_2d_3x3.cc +++ b/mace/ops/opencl/image/conv_2d_3x3.cc @@ -16,7 +16,7 @@ #include "mace/core/runtime/opencl/opencl_runtime.h" #include "mace/ops/common/activation_type.h" #include "mace/ops/opencl/helper.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { namespace ops { diff --git a/mace/ops/opencl/image/conv_2d_general.cc b/mace/ops/opencl/image/conv_2d_general.cc index 08568a5d9e39d671a2e3d84de8fc1fa22c588f95..7f0250cbc4ebc73cfa52c6041c9da8c95b7e3892 100644 --- a/mace/ops/opencl/image/conv_2d_general.cc +++ b/mace/ops/opencl/image/conv_2d_general.cc @@ -16,7 +16,7 @@ #include "mace/core/runtime/opencl/opencl_runtime.h" #include "mace/ops/opencl/helper.h" #include "mace/ops/common/activation_type.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { namespace ops { diff --git a/mace/ops/opencl/image/winograd_conv2d.cc b/mace/ops/opencl/image/winograd_conv2d.cc index 0bda447005a413e2503a096cd18defe4a181ce0e..27a0bc30533f4538a537dc6c3084178ee1d5d3cd 100644 --- a/mace/ops/opencl/image/winograd_conv2d.cc +++ b/mace/ops/opencl/image/winograd_conv2d.cc @@ -18,7 +18,7 @@ #include "mace/ops/common/conv_pool_2d_util.h" #include "mace/ops/opencl/helper.h" #include "mace/utils/memory.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { namespace ops { diff --git a/mace/ops/opencl/lstm_cell.h b/mace/ops/opencl/lstm_cell.h index 07ea2e65551092d5c8dcfe561a2dcaecc8c9261a..4dee034c12fa858fea262e2977d5383b5863e9b3 100644 --- a/mace/ops/opencl/lstm_cell.h +++ b/mace/ops/opencl/lstm_cell.h @@ -16,7 +16,7 @@ #define MACE_OPS_OPENCL_LSTM_CELL_H_ #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/matmul.h b/mace/ops/opencl/matmul.h index c51c83c146fdc7834de05522f8ab6939f4974673..05879f8ae2ed8623652316d13e0526e48a584b3b 100644 --- a/mace/ops/opencl/matmul.h +++ b/mace/ops/opencl/matmul.h @@ -16,7 +16,7 @@ #define MACE_OPS_OPENCL_MATMUL_H_ #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/pad.h b/mace/ops/opencl/pad.h index cfc7edb3a1351e1b9bf8d1a152e4d906c6f09d47..640137691964b9e57cca9e69ee0c73a8d85420f0 100644 --- a/mace/ops/opencl/pad.h +++ b/mace/ops/opencl/pad.h @@ -16,7 +16,7 @@ #define MACE_OPS_OPENCL_PAD_H_ #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { class OpContext; diff --git a/mace/ops/opencl/reduce.h b/mace/ops/opencl/reduce.h index 4f6aa2187561a22ac0e6758b45738a73a6bf9fa7..f653f8b02805dfb387d38b617eed2256e70255d9 100644 --- a/mace/ops/opencl/reduce.h +++ b/mace/ops/opencl/reduce.h @@ -16,7 +16,7 @@ #define MACE_OPS_OPENCL_REDUCE_H_ #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/resize_bicubic.h b/mace/ops/opencl/resize_bicubic.h index 4fde45453b6335e2ca1a1eab8c57f909b253e97b..b7fd71a0dbcddc85322fae1b2a8973a1b63af1b5 100644 --- a/mace/ops/opencl/resize_bicubic.h +++ b/mace/ops/opencl/resize_bicubic.h @@ -16,7 +16,7 @@ #define MACE_OPS_OPENCL_RESIZE_BICUBIC_H_ #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" #include "mace/core/types.h" namespace mace { diff --git a/mace/ops/opencl/resize_bilinear.h b/mace/ops/opencl/resize_bilinear.h index 18dd312845b0bcba5ed91a1f9ad5aa0311e2279a..66035d8511136952eeefe92efce0a3fd614aad5e 100644 --- a/mace/ops/opencl/resize_bilinear.h +++ b/mace/ops/opencl/resize_bilinear.h @@ -17,7 +17,7 @@ #include "mace/core/types.h" #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/resize_nearest_neighbor.h b/mace/ops/opencl/resize_nearest_neighbor.h index fda220aee9704228d435a304001a5f679f2d28e3..b0178827ac6190d413b179b4a98c367d1e5f9c37 100644 --- a/mace/ops/opencl/resize_nearest_neighbor.h +++ b/mace/ops/opencl/resize_nearest_neighbor.h @@ -17,7 +17,7 @@ #include "mace/core/types.h" #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/softmax.h b/mace/ops/opencl/softmax.h index caca5dc693a6d2e8735edc91a0f5c9f0feab65c4..a4a439ec1501db36a417c2d533d14cf1bea103e5 100644 --- a/mace/ops/opencl/softmax.h +++ b/mace/ops/opencl/softmax.h @@ -16,7 +16,7 @@ #define MACE_OPS_OPENCL_SOFTMAX_H_ #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/space_to_batch.h b/mace/ops/opencl/space_to_batch.h index 350bf120975c6e3747e8cb5c848d9eb88f646d71..9f73ff5acdfaaa7956219bff51c42c4beb9c40b4 100644 --- a/mace/ops/opencl/space_to_batch.h +++ b/mace/ops/opencl/space_to_batch.h @@ -19,7 +19,7 @@ #include "mace/core/types.h" #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/space_to_depth.h b/mace/ops/opencl/space_to_depth.h index 69e40c82a0e3d7d06cd181d52bb71f7f1b7bd8e0..454cb686e7d1589c3c1329cc97d7a60b3c9ed663 100644 --- a/mace/ops/opencl/space_to_depth.h +++ b/mace/ops/opencl/space_to_depth.h @@ -16,7 +16,7 @@ #define MACE_OPS_OPENCL_SPACE_TO_DEPTH_H_ #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/split.h b/mace/ops/opencl/split.h index 61f75d85c6f2c3032eacbeb908bb79edf61c26ea..8c7ac5636b77a1d07449d6f8ce09c77a6934b537 100644 --- a/mace/ops/opencl/split.h +++ b/mace/ops/opencl/split.h @@ -18,7 +18,7 @@ #include #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { diff --git a/mace/ops/opencl/sqrdiff_mean.h b/mace/ops/opencl/sqrdiff_mean.h index 822b992f0009726210126bcb19d06f480dcbf7ca..781a08c56568bf6f27230abd109d53ab24faa7e3 100644 --- a/mace/ops/opencl/sqrdiff_mean.h +++ b/mace/ops/opencl/sqrdiff_mean.h @@ -16,7 +16,7 @@ #define MACE_OPS_OPENCL_SQRDIFF_MEAN_H_ #include "mace/public/mace.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" namespace mace { class OpContext; diff --git a/mace/ops/ops_test_util.h b/mace/ops/ops_test_util.h index f60fff1d39cb86e51b8c63dae1f94fc4089efb41..19fe05d32e9f850d8a77cdadf1008c78b74b9ef7 100644 --- a/mace/ops/ops_test_util.h +++ b/mace/ops/ops_test_util.h @@ -35,7 +35,7 @@ #include "mace/ops/ops_registry.h" #include "mace/public/mace.h" #include "mace/utils/memory.h" -#include "mace/utils/utils.h" +#include "mace/utils/math.h" #include "mace/utils/quantize.h" #include "mace/ops/testing/test_utils.h" diff --git a/mace/ops/pad.cc b/mace/ops/pad.cc index 7c20edd9fdd07e5fef11b5719f170d8c35946f51..aaa6b230f4b5237dc88d16e369dcf289a8fe9df6 100644 --- a/mace/ops/pad.cc +++ b/mace/ops/pad.cc @@ -21,6 +21,7 @@ #include "mace/ops/opencl/image/pad.h" #endif // MACE_ENABLE_OPENCL #include "mace/utils/memory.h" +#include "mace/utils/math.h" namespace mace { namespace ops { diff --git a/mace/ops/reduce.cc b/mace/ops/reduce.cc index 860660be825fbdb2cf980e8b136cfde0909bd155..068212f204d85a3129d1f7ad9e9cbe0cfca06491 100644 --- a/mace/ops/reduce.cc +++ b/mace/ops/reduce.cc @@ -85,7 +85,7 @@ class ReduceOp : public ReduceOpBase { private: void Simplify(const Tensor *input) { std::vector bitmap(static_cast(input->dim_size()), false); - if (axis_.size() == 0) { + if (axis_.empty()) { for (int i = 0; i < input->dim_size(); ++i) { bitmap[i] = true; } diff --git a/mace/ops/reshape.cc b/mace/ops/reshape.cc index e578e69aec0f314e854c70fabd411c61bc3f81bc..98ea215e7678b32170bf98d415b0c88ec23a60e6 100644 --- a/mace/ops/reshape.cc +++ b/mace/ops/reshape.cc @@ -15,6 +15,7 @@ #include #include "mace/core/operator.h" +#include "mace/utils/math.h" namespace mace { namespace ops { diff --git a/mace/ops/softmax.cc b/mace/ops/softmax.cc index 693058a372198f7eb0848ef84e9aab78e4e2645c..cbab37adf5ebe9e0a3195483cecc287be5931bd0 100644 --- a/mace/ops/softmax.cc +++ b/mace/ops/softmax.cc @@ -134,10 +134,10 @@ class SoftmaxOp : public Operation { } }; +#ifdef MACE_ENABLE_QUANTIZE static const int kInputDeltaIntBits = 6; static const int kSumExpIntBits = 12; -#ifdef MACE_ENABLE_QUANTIZE template <> class SoftmaxOp : public Operation { public: diff --git a/mace/ops/splice.cc b/mace/ops/splice.cc index 9093b8aada66d2ccdf69ca5ae27bfb19322bced6..bf1dfe36b41e8c79675f3d75b0578fa2ce76816e 100644 --- a/mace/ops/splice.cc +++ b/mace/ops/splice.cc @@ -32,6 +32,7 @@ #include #include "mace/core/operator.h" +#include "mace/utils/math.h" namespace mace { namespace ops { diff --git a/mace/ops/testing/test_utils.h b/mace/ops/testing/test_utils.h index 59e71448f6421d51a8d67f77d17e49420fe7a915..6a0a045b6326a67689f9755bc911a2f54fbc798a 100644 --- a/mace/ops/testing/test_utils.h +++ b/mace/ops/testing/test_utils.h @@ -27,6 +27,7 @@ #include #include "mace/core/tensor.h" +#include "gtest/gtest.h" namespace mace { namespace ops { diff --git a/mace/ops/time_offset.cc b/mace/ops/time_offset.cc index 2fff53c1124e2795551fed7d55b588c101489096..d9343fc327438a965fe4b3e98a583783a6d4993a 100644 --- a/mace/ops/time_offset.cc +++ b/mace/ops/time_offset.cc @@ -19,6 +19,7 @@ #include #include "mace/core/operator.h" +#include "mace/utils/math.h" namespace mace { namespace ops { diff --git a/mace/port/BUILD.bazel b/mace/port/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..30db894567f71c603ab00ca4a7520d35289636f7 --- /dev/null +++ b/mace/port/BUILD.bazel @@ -0,0 +1,52 @@ +package( + default_visibility = ["//visibility:public"], +) + +licenses(["notice"]) # Apache 2.0 + +cc_library( + name = "port", + deps = [ + "//mace/port/android:port_android", + "//mace/port/darwin:port_darwin", + "//mace/port/linux:port_linux", + ], +) + +cc_library( + name = "port_api", + hdrs = [ + "env.h", + "file_system.h", + "logger.h", + ], + deps = [ + "//mace/public", + ], +) + +cc_library( + name = "port_base", + srcs = [ + "env.cc", + "logger.cc", + ], + deps = [ + ":port_api", + "//mace/utils", + ], +) + +cc_test( + name = "port_test", + testonly = 1, + srcs = glob([ + "*_test.cc", + ]), + linkstatic = 0, + deps = [ + ":port", + "@gtest//:gtest", + "@gtest//:gtest_main", + ], +) diff --git a/mace/port/README.md b/mace/port/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9ecfff01571db8bcfa4733e1f4e4979763b81d8d --- /dev/null +++ b/mace/port/README.md @@ -0,0 +1,14 @@ +# port + +This module contains the interface and implementations for different platforms. +All platform specific code should go here. It's not allowed to use non standard +headers in other modules. + +This module splits into `port_api` and `port`. `port_api` is the interface, and +it should not depends on any other modules including `utils`. + +If the code base goes large in the future, it should be split into core and +test to keep the footprint for production libs as small as possible. + +Currently Linux, Darwin (MacOS, iOS etc.) are treated as POSIX. They will be +handled differently if needed. diff --git a/mace/port/android/BUILD.bazel b/mace/port/android/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..fd5aacc51f3653a32a6fa4b5f5752772d6dd20bc --- /dev/null +++ b/mace/port/android/BUILD.bazel @@ -0,0 +1,22 @@ +package( + default_visibility = ["//visibility:public"], +) + +licenses(["notice"]) # Apache 2.0 + +load("//mace:mace.bzl", "if_android") + +cc_library( + name = "port_android", + srcs = if_android(glob([ + "*.cc", + ])), + hdrs = if_android(glob([ + "*.h", + ])), + deps = [ + "//mace/port:port_base", + "//mace/port/posix:port_posix", + ], + alwayslink = 1, +) diff --git a/mace/port/android/env.cc b/mace/port/android/env.cc new file mode 100644 index 0000000000000000000000000000000000000000..774511fdfbb4ac26ea514f4f799d619c8188cf85 --- /dev/null +++ b/mace/port/android/env.cc @@ -0,0 +1,204 @@ +// Copyright 2019 The MACE Authors. 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 "mace/port/android/env.h" + +#include +#include +#include +#include +#include +#include + +#ifdef __hexagon__ +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include "mace/port/android/malloc_logger.h" +#include "mace/port/posix/time.h" +#include "mace/utils/macros.h" +#include "mace/utils/memory.h" +#include "mace/utils/logging.h" + +namespace mace { +namespace port { + +int64_t AndroidEnv::NowMicros() { +#ifdef __hexagon__ + return HAP_perf_get_time_us(); +#else + return mace::port::posix::NowMicros(); +#endif +} + +FileSystem *AndroidEnv::GetFileSystem() { + return &posix_file_system_; +} + +LogWriter *AndroidEnv::GetLogWriter() { + return &log_writer_; +} + +namespace { + +int GetCpuCount() { + int cpu_count = 0; + std::string cpu_sys_conf = "/proc/cpuinfo"; + std::ifstream f(cpu_sys_conf); + if (!f.is_open()) { + LOG(ERROR) << "failed to open " << cpu_sys_conf; + return -1; + } + std::string line; + const std::string processor_key = "processor"; + while (std::getline(f, line)) { + if (line.size() >= processor_key.size() + && line.compare(0, processor_key.size(), processor_key) == 0) { + ++cpu_count; + } + } + if (f.bad()) { + LOG(ERROR) << "failed to read " << cpu_sys_conf; + } + if (!f.eof()) { + LOG(ERROR) << "failed to read end of " << cpu_sys_conf; + } + f.close(); + VLOG(1) << "CPU cores: " << cpu_count; + return cpu_count; +} + +struct BacktraceState { + void** current; + void** end; +}; + +_Unwind_Reason_Code UnwindCallback(struct _Unwind_Context* context, void* arg) { + BacktraceState* state = static_cast(arg); + uintptr_t pc = _Unwind_GetIP(context); + if (pc) { + if (state->current == state->end) { + return _URC_END_OF_STACK; + } else { + *state->current++ = reinterpret_cast(pc); + } + } + return _URC_NO_REASON; +} + +size_t BackTrace(void** buffer, size_t max) { + BacktraceState state = {buffer, buffer + max}; + _Unwind_Backtrace(UnwindCallback, &state); + + return state.current - buffer; +} + +} // namespace + +MaceStatus AndroidEnv::GetCpuMaxFreq(std::vector *max_freqs) { + MACE_CHECK_NOTNULL(max_freqs); + int cpu_count = GetCpuCount(); + if (cpu_count < 0) { + return MaceStatus::MACE_RUNTIME_ERROR; + } + for (int cpu_id = 0; cpu_id < cpu_count; ++cpu_id) { + std::string cpuinfo_max_freq_sys_conf = MakeString( + "/sys/devices/system/cpu/cpu", + cpu_id, + "/cpufreq/cpuinfo_max_freq"); + std::ifstream f(cpuinfo_max_freq_sys_conf); + if (!f.is_open()) { + LOG(ERROR) << "failed to open " << cpuinfo_max_freq_sys_conf; + return MaceStatus::MACE_RUNTIME_ERROR; + } + std::string line; + if (std::getline(f, line)) { + float freq = strtof(line.c_str(), nullptr); + max_freqs->push_back(freq); + } + if (f.bad()) { + LOG(ERROR) << "failed to read " << cpuinfo_max_freq_sys_conf; + } + f.close(); + } + + if (VLOG_IS_ON(1)) VLOG(1) << "CPU freq: " << MakeString(*max_freqs); + + return MaceStatus::MACE_SUCCESS; +} + +MaceStatus AndroidEnv::SchedSetAffinity(const std::vector &cpu_ids) { + // compute mask + cpu_set_t mask; + CPU_ZERO(&mask); + for (auto cpu_id : cpu_ids) { + CPU_SET(cpu_id, &mask); + } + pid_t pid = gettid(); + int err = sched_setaffinity(pid, sizeof(mask), &mask); + if (err) { + LOG(WARNING) << "SchedSetAffinity failed: " << strerror(errno); + return MaceStatus(MaceStatus::MACE_INVALID_ARGS, + "SchedSetAffinity failed: " + + std::string(strerror(errno))); + } + + return MaceStatus::MACE_SUCCESS; +} + +std::vector AndroidEnv::GetBackTraceUnsafe(int max_steps) { + std::vector buffer(max_steps, 0); + int steps = BackTrace(buffer.data(), max_steps); + + std::vector bt; + for (int i = 0; i < steps; ++i) { + std::ostringstream os; + + const void* addr = buffer[i]; + const char* symbol = ""; + Dl_info info; + if (dladdr(addr, &info) && info.dli_sname) { + symbol = info.dli_sname; + } + + os << "pc " << addr << " " << symbol; + + bt.push_back(os.str()); + } + + return bt; +} + +std::unique_ptr AndroidEnv::NewMallocLogger( + std::ostringstream *oss, + const std::string &name) { + return make_unique(oss, name); +} + +Env *Env::Default() { + static AndroidEnv android_env; + return &android_env; +} + +} // namespace port +} // namespace mace diff --git a/mace/port/android/env.h b/mace/port/android/env.h new file mode 100644 index 0000000000000000000000000000000000000000..04c3b35b98b66c17f6c191a749abe74dc82825ab --- /dev/null +++ b/mace/port/android/env.h @@ -0,0 +1,49 @@ +// Copyright 2019 The MACE Authors. 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. + +#ifndef MACE_PORT_ANDROID_ENV_H_ +#define MACE_PORT_ANDROID_ENV_H_ + +#include +#include +#include + +#include "mace/port/android/logger.h" +#include "mace/port/posix/file_system.h" +#include "mace/port/env.h" + +namespace mace { +namespace port { + +class AndroidEnv : public Env { + public: + int64_t NowMicros() override; + MaceStatus GetCpuMaxFreq(std::vector *max_freqs) override; + MaceStatus SchedSetAffinity(const std::vector &cpu_ids) override; + FileSystem *GetFileSystem() override; + LogWriter *GetLogWriter() override; + std::vector GetBackTraceUnsafe(int max_steps) override; + std::unique_ptr NewMallocLogger( + std::ostringstream *oss, + const std::string &name) override; + + private: + PosixFileSystem posix_file_system_; + AndroidLogWriter log_writer_; +}; + +} // namespace port +} // namespace mace + +#endif // MACE_PORT_ANDROID_ENV_H_ diff --git a/mace/port/android/logger.cc b/mace/port/android/logger.cc new file mode 100644 index 0000000000000000000000000000000000000000..c0fd5f6bceaa36f41dc964c02396af20a718318a --- /dev/null +++ b/mace/port/android/logger.cc @@ -0,0 +1,58 @@ +// Copyright 2019 The MACE Authors. 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 "mace/port/android/logger.h" + +#include + +#include + +namespace mace { +namespace port { + +void AndroidLogWriter::WriteLogMessage(const char *fname, + const int line, + const LogLevel severity, + const char *message) { + int android_log_level; + switch (severity) { + case INFO: + android_log_level = ANDROID_LOG_INFO; + break; + case WARNING: + android_log_level = ANDROID_LOG_WARN; + break; + case ERROR: + android_log_level = ANDROID_LOG_ERROR; + break; + case FATAL: + android_log_level = ANDROID_LOG_FATAL; + break; + default: + android_log_level = ANDROID_LOG_ERROR; + break; + } + + std::stringstream ss; + const char *const partial_name = strrchr(fname, '/'); + ss << (partial_name != nullptr ? partial_name + 1 : fname) << ":" << line + << " " << message; + __android_log_write(android_log_level, "CRT", ss.str().c_str()); + + // Also log to stderr (for standalone Android apps) and abort. + LogWriter::WriteLogMessage(fname, line, severity, message); +} + +} // namespace port +} // namespace mace diff --git a/mace/port/android/logger.h b/mace/port/android/logger.h new file mode 100644 index 0000000000000000000000000000000000000000..fccfb83515c360bf61245dfcabfe73776b7702a7 --- /dev/null +++ b/mace/port/android/logger.h @@ -0,0 +1,34 @@ +// Copyright 2019 The MACE Authors. 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. + +#ifndef MACE_PORT_ANDROID_LOGGER_H_ +#define MACE_PORT_ANDROID_LOGGER_H_ + +#include "mace/port/logger.h" + +namespace mace { +namespace port { + +class AndroidLogWriter : public LogWriter { + protected: + void WriteLogMessage(const char *fname, + const int line, + const LogLevel severity, + const char *message) override; +}; + +} // namespace port +} // namespace mace + +#endif // MACE_PORT_ANDROID_LOGGER_H_ diff --git a/mace/port/android/malloc_logger.cc b/mace/port/android/malloc_logger.cc new file mode 100644 index 0000000000000000000000000000000000000000..afaef724309d103ed15ac584b8f41c49d92c363d --- /dev/null +++ b/mace/port/android/malloc_logger.cc @@ -0,0 +1,100 @@ +// Copyright 2019 The MACE Authors. 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 "mace/port/android/malloc_logger.h" + +#include + +#include +#include + +namespace mace { +namespace port { + +namespace { +struct mallinfo LogMallinfoChange(std::ostringstream *oss, + const std::string &name, + const struct mallinfo curr, + const struct mallinfo prev) { + if (prev.arena != curr.arena) { + (*oss) << "[" << name << "] " + << "Non-mmapped space allocated (bytes): " << curr.arena + << ", diff: " << ((int64_t)curr.arena - (int64_t)prev.arena); + } + if (prev.ordblks != curr.ordblks) { + (*oss) << "[" << name << "] " + << "Number of free chunks: " << curr.ordblks << ", diff: " + << ((int64_t)curr.ordblks - (int64_t)prev.ordblks); + } + if (prev.smblks != curr.smblks) { + (*oss) << "[" << name << "] " + << "Number of free fastbin blocks: " << curr.smblks + << ", diff: " << ((int64_t)curr.smblks - (int64_t)prev.smblks); + } + if (prev.hblks != curr.hblks) { + (*oss) << "[" << name << "] " + << "Number of mmapped regions: " << curr.hblks + << ", diff: " << ((int64_t)curr.hblks - (int64_t)prev.hblks); + } + if (prev.hblkhd != curr.hblkhd) { + (*oss) << "[" << name << "] " + << "Space allocated in mmapped regions (bytes): " << curr.hblkhd + << ", diff: " << ((int64_t)curr.hblkhd - (int64_t)prev.hblkhd); + } + if (prev.usmblks != curr.usmblks) { + (*oss) << "[" << name << "] " + << "Maximum total allocated space (bytes): " << curr.usmblks + << ", diff: " + << ((int64_t)curr.usmblks - (int64_t)prev.usmblks); + } + if (prev.fsmblks != curr.fsmblks) { + (*oss) << "[" << name << "] " + << "Space in freed fastbin blocks (bytes): " << curr.fsmblks + << ", diff: " + << ((int64_t)curr.fsmblks - (int64_t)prev.fsmblks); + } + if (prev.uordblks != curr.uordblks) { + (*oss) << "[" << name << "] " + << "Total allocated space (bytes): " << curr.uordblks + << ", diff: " + << ((int64_t)curr.uordblks - (int64_t)prev.uordblks); + } + if (prev.fordblks != curr.fordblks) { + (*oss) << "[" << name << "] " + << "Total free space (bytes): " << curr.fordblks << ", diff: " + << ((int64_t)curr.fordblks - (int64_t)prev.fordblks); + } + if (prev.keepcost != curr.keepcost) { + (*oss) << "[" << name << "] " + << "Top-most, releasable space (bytes): " << curr.keepcost + << ", diff: " + << ((int64_t)curr.keepcost - (int64_t)prev.keepcost); + } + return curr; +} +} // namespace + +AndroidMallocLogger::AndroidMallocLogger(std::ostringstream *oss, + const std::string &name) : + oss_(oss), name_(name) { + prev_ = mallinfo(); +} + +AndroidMallocLogger::~AndroidMallocLogger() { + struct mallinfo curr = mallinfo(); + LogMallinfoChange(oss_, name_, curr, prev_); +} + +} // namespace port +} // namespace mace diff --git a/mace/port/android/malloc_logger.h b/mace/port/android/malloc_logger.h new file mode 100644 index 0000000000000000000000000000000000000000..9bc7052455b1a8445fa8b0719a82c956a6436ea4 --- /dev/null +++ b/mace/port/android/malloc_logger.h @@ -0,0 +1,43 @@ +// Copyright 2019 The MACE Authors. 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. + +#ifndef MACE_PORT_ANDROID_MALLOC_LOGGER_H_ +#define MACE_PORT_ANDROID_MALLOC_LOGGER_H_ + +#include + +#include + +#include "mace/port/env.h" + +namespace mace { +namespace port { + +class AndroidMallocLogger : public MallocLogger { + public: + explicit AndroidMallocLogger(std::ostringstream *oss, + const std::string &name); + ~AndroidMallocLogger() override; + + private: + std::ostringstream *oss_; + const std::string name_; + struct mallinfo prev_; +}; + +} // namespace port +} // namespace mace + + +#endif // MACE_PORT_ANDROID_MALLOC_LOGGER_H_ diff --git a/mace/port/darwin/BUILD.bazel b/mace/port/darwin/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..987dafd16ea22f3f8b5b97052d0672f18c81c98d --- /dev/null +++ b/mace/port/darwin/BUILD.bazel @@ -0,0 +1,22 @@ +package( + default_visibility = ["//visibility:public"], +) + +licenses(["notice"]) # Apache 2.0 + +load("//mace:mace.bzl", "if_darwin") + +cc_library( + name = "port_darwin", + srcs = if_darwin(glob([ + "*.cc", + ])), + hdrs = if_darwin(glob([ + "*.h", + ])), + deps = [ + "//mace/port:port_base", + "//mace/port/posix:port_posix", + ], + alwayslink = 1, +) diff --git a/mace/port/darwin/env.cc b/mace/port/darwin/env.cc new file mode 100644 index 0000000000000000000000000000000000000000..f951e64753b9736705b67153a7ef3ba82cb72e73 --- /dev/null +++ b/mace/port/darwin/env.cc @@ -0,0 +1,53 @@ +// Copyright 2019 The MACE Authors. 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 "mace/port/darwin/env.h" + +#include +#include + +#include +#include +#include + +#include "mace/port/posix/backtrace.h" +#include "mace/port/posix/file_system.h" +#include "mace/port/posix/time.h" + +namespace mace { +namespace port { + +int64_t DarwinEnv::NowMicros() { + return mace::port::posix::NowMicros(); +} + +FileSystem *DarwinEnv::GetFileSystem() { + return &posix_file_system_; +} + +LogWriter *DarwinEnv::GetLogWriter() { + return &log_writer_; +} + +std::vector DarwinEnv::GetBackTraceUnsafe(int max_steps) { + return mace::port::posix::GetBackTraceUnsafe(max_steps); +} + +Env *Env::Default() { + static DarwinEnv darwin_env; + return &darwin_env; +} + +} // namespace port +} // namespace mace diff --git a/mace/port/darwin/env.h b/mace/port/darwin/env.h new file mode 100644 index 0000000000000000000000000000000000000000..667cf9f0a0e2f102c1ddc183605eea1f22dfa0c6 --- /dev/null +++ b/mace/port/darwin/env.h @@ -0,0 +1,43 @@ +// Copyright 2019 The MACE Authors. 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. + +#ifndef MACE_PORT_DARWIN_ENV_H_ +#define MACE_PORT_DARWIN_ENV_H_ + +#include +#include + +#include "mace/port/env.h" +#include "mace/port/logger.h" +#include "mace/port/posix/file_system.h" + +namespace mace { +namespace port { + +class DarwinEnv : public Env { + public: + int64_t NowMicros() override; + FileSystem *GetFileSystem() override; + LogWriter *GetLogWriter() override; + std::vector GetBackTraceUnsafe(int max_steps) override; + + private: + PosixFileSystem posix_file_system_; + LogWriter log_writer_; +}; + +} // namespace port +} // namespace mace + +#endif // MACE_PORT_DARWIN_ENV_H_ diff --git a/mace/port/env.cc b/mace/port/env.cc new file mode 100644 index 0000000000000000000000000000000000000000..10ae4306f8b5d11ea2e15540539428f604d23e35 --- /dev/null +++ b/mace/port/env.cc @@ -0,0 +1,40 @@ +// Copyright 2019 The MACE Authors. 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 "mace/port/env.h" + +#include + +#include "mace/utils/memory.h" +#include "mace/public/mace.h" + +namespace mace { +namespace port { + +MaceStatus Env::GetCpuMaxFreq(std::vector *max_freqs) { + return MaceStatus::MACE_UNSUPPORTED; +} + +MaceStatus Env::SchedSetAffinity(const std::vector &cpu_ids) { + return MaceStatus::MACE_UNSUPPORTED; +} + +std::unique_ptr Env::NewMallocLogger( + std::ostringstream *oss, + const std::string &name) { + return make_unique(); +} + +} // namespace port +} // namespace mace diff --git a/mace/port/env.h b/mace/port/env.h new file mode 100644 index 0000000000000000000000000000000000000000..2491f023f4ef717a96218e5542ce4942b5afe9d0 --- /dev/null +++ b/mace/port/env.h @@ -0,0 +1,75 @@ +// Copyright 2019 The MACE Authors. 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. + +#ifndef MACE_PORT_ENV_H_ +#define MACE_PORT_ENV_H_ + +#include +#include +#include +#include +#include + +#include "mace/public/mace.h" + +namespace mace { +namespace port { + +class MallocLogger { + public: + MallocLogger() = default; + virtual ~MallocLogger() = default; +}; + +class FileSystem; +class LogWriter; + +class Env { + public: + virtual int64_t NowMicros() = 0; + virtual MaceStatus GetCpuMaxFreq(std::vector *max_freqs); + virtual MaceStatus SchedSetAffinity(const std::vector &cpu_ids); + virtual FileSystem *GetFileSystem() = 0; + virtual LogWriter *GetLogWriter() = 0; + // Return the current backtrace, will allocate memory inside the call + // which may fail + virtual std::vector GetBackTraceUnsafe(int max_steps) = 0; + virtual std::unique_ptr NewMallocLogger( + std::ostringstream *oss, + const std::string &name); + + static Env *Default(); +}; + +} // namespace port + +inline int64_t NowMicros() { + return port::Env::Default()->NowMicros(); +} + +inline MaceStatus GetCpuMaxFreq(std::vector *max_freqs) { + return port::Env::Default()->GetCpuMaxFreq(max_freqs); +} + +inline MaceStatus SchedSetAffinity(const std::vector &cpu_ids) { + return port::Env::Default()->SchedSetAffinity(cpu_ids); +} + +inline port::FileSystem *GetFileSystem() { + return port::Env::Default()->GetFileSystem(); +} + +} // namespace mace + +#endif // MACE_PORT_ENV_H_ diff --git a/mace/port/env_test.cc b/mace/port/env_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..1a61554522c6240fb80795aadebb16de6857f42d --- /dev/null +++ b/mace/port/env_test.cc @@ -0,0 +1,41 @@ +// Copyright 2019 The MACE Authors. 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 "mace/port/env.h" + +#include + +namespace mace { +namespace { + +class EnvTest : public ::testing::Test { +}; + +TEST_F(EnvTest, NowMicros) { + EXPECT_GT(NowMicros(), 0); +} + +TEST_F(EnvTest, GetFileSystem) { + GetFileSystem(); +} + +TEST_F(EnvTest, CpuInfo) { + std::vector freq; + GetCpuMaxFreq(&freq); + std::vector cpu_ids; + SchedSetAffinity(cpu_ids); +} + +} // namespace +} // namespace mace diff --git a/mace/port/file_system.h b/mace/port/file_system.h new file mode 100644 index 0000000000000000000000000000000000000000..91b6f458d3a021c9163e7cc07c1404805f2aae43 --- /dev/null +++ b/mace/port/file_system.h @@ -0,0 +1,45 @@ +// Copyright 2019 The MACE Authors. 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. + +#ifndef MACE_PORT_FILE_SYSTEM_H_ +#define MACE_PORT_FILE_SYSTEM_H_ + +#include +#include + +#include "mace/public/mace.h" + +namespace mace { +namespace port { + +class ReadOnlyMemoryRegion { + public: + ReadOnlyMemoryRegion() = default; + virtual ~ReadOnlyMemoryRegion() = default; + virtual const void *data() = 0; + virtual uint64_t length() = 0; +}; + +class FileSystem { + public: + FileSystem() = default; + virtual ~FileSystem() = default; + virtual MaceStatus NewReadOnlyMemoryRegionFromFile(const char *fname, + std::unique_ptr* result) = 0; +}; + +} // namespace port +} // namespace mace + +#endif // MACE_PORT_FILE_SYSTEM_H_ diff --git a/mace/port/linux/BUILD.bazel b/mace/port/linux/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..5d1351baf844c4e90f6259fddb97b6217dd769b2 --- /dev/null +++ b/mace/port/linux/BUILD.bazel @@ -0,0 +1,22 @@ +package( + default_visibility = ["//visibility:public"], +) + +licenses(["notice"]) # Apache 2.0 + +load("//mace:mace.bzl", "if_linux") + +cc_library( + name = "port_linux", + srcs = if_linux(glob([ + "*.cc", + ])), + hdrs = if_linux(glob([ + "*.h", + ])), + deps = [ + "//mace/port:port_base", + "//mace/port/posix:port_posix", + ], + alwayslink = 1, +) diff --git a/mace/port/linux/env.cc b/mace/port/linux/env.cc new file mode 100644 index 0000000000000000000000000000000000000000..2a50b4a1198049d5610f3daad5b33f47efb97c4a --- /dev/null +++ b/mace/port/linux/env.cc @@ -0,0 +1,53 @@ +// Copyright 2019 The MACE Authors. 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 "mace/port/linux/env.h" + +#include +#include + +#include +#include +#include + +#include "mace/port/posix/backtrace.h" +#include "mace/port/posix/file_system.h" +#include "mace/port/posix/time.h" + +namespace mace { +namespace port { + +int64_t LinuxEnv::NowMicros() { + return mace::port::posix::NowMicros(); +} + +FileSystem *LinuxEnv::GetFileSystem() { + return &posix_file_system_; +} + +LogWriter *LinuxEnv::GetLogWriter() { + return &log_writer_; +} + +std::vector LinuxEnv::GetBackTraceUnsafe(int max_steps) { + return mace::port::posix::GetBackTraceUnsafe(max_steps); +} + +Env *Env::Default() { + static LinuxEnv linux_env; + return &linux_env; +} + +} // namespace port +} // namespace mace diff --git a/mace/port/linux/env.h b/mace/port/linux/env.h new file mode 100644 index 0000000000000000000000000000000000000000..5d1d243a1ab616c3bf13d6d9069147e7cced4519 --- /dev/null +++ b/mace/port/linux/env.h @@ -0,0 +1,43 @@ +// Copyright 2019 The MACE Authors. 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. + +#ifndef MACE_PORT_LINUX_ENV_H_ +#define MACE_PORT_LINUX_ENV_H_ + +#include +#include + +#include "mace/port/env.h" +#include "mace/port/logger.h" +#include "mace/port/posix/file_system.h" + +namespace mace { +namespace port { + +class LinuxEnv : public Env { + public: + int64_t NowMicros() override; + FileSystem *GetFileSystem() override; + LogWriter *GetLogWriter() override; + std::vector GetBackTraceUnsafe(int max_steps) override; + + private: + PosixFileSystem posix_file_system_; + LogWriter log_writer_; +}; + +} // namespace port +} // namespace mace + +#endif // MACE_PORT_LINUX_ENV_H_ diff --git a/mace/port/logger.cc b/mace/port/logger.cc new file mode 100644 index 0000000000000000000000000000000000000000..b02f6f4455d92a275470c0c762edf20c257d2b38 --- /dev/null +++ b/mace/port/logger.cc @@ -0,0 +1,115 @@ +// Copyright 2019 The MACE Authors. 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 "mace/port/logger.h" + +#include +#include +#include +#include + +#include "mace/port/env.h" +#include "mace/utils/string_util.h" + +namespace mace { +namespace port { + +inline bool IsValidLogLevel(const LogLevel level) { + return level > LogLevel::INVALID_MIN && + level < LogLevel::INVALID_MAX; +} + +LogLevel LogLevelFromStr(const char *log_level_str) { + if (log_level_str != nullptr) { + std::string ls = ToUpper(log_level_str); + + if (ls == "I" || ls == "INFO") { + return LogLevel::INFO; + } + if (ls == "W" || ls == "WARNING") { + return LogLevel::WARNING; + } + if (ls == "E" || ls == "ERROR") { + return LogLevel::ERROR; + } + if (ls == "F" || ls == "FATAL") { + return LogLevel::FATAL; + } + } + + return LogLevel::INVALID_MIN; +} + +char LogLevelToShortStr(LogLevel level) { + if (!IsValidLogLevel(level)) { + level = LogLevel::INFO; + } + + return "IWEF"[static_cast(level) - 1]; +} + +int VLogLevelFromStr(const char *vlog_level_str) { + if (vlog_level_str != nullptr) { + return atoi(vlog_level_str); + } + + return 0; +} + + +void LogWriter::WriteLogMessage(const char *fname, + const int line, + const LogLevel severity, + const char *message) { + printf("%c %s:%d] %s\n", LogLevelToShortStr(severity), fname, line, message); +} + +Logger::Logger(const char *fname, int line, LogLevel severity) + : fname_(fname), line_(line), severity_(severity) {} + +void Logger::GenerateLogMessage() { + LogWriter *log_writer = Env::Default()->GetLogWriter(); + log_writer->WriteLogMessage(fname_, line_, severity_, str().c_str()); + + // When there is a fatal log, terminate execution + if (severity_ == LogLevel::FATAL) { + DealWithFatal(); + } +} + +void Logger::DealWithFatal() { + // When there is a fatal log, log the backtrace and abort. + LogWriter *log_writer = Env::Default()->GetLogWriter(); + std::vector bt = Env::Default()->GetBackTraceUnsafe(50); + if (!bt.empty()) { + log_writer->WriteLogMessage(fname_, line_, severity_, "backtrace:"); + for (size_t i = 0; i < bt.size(); ++i) { + std::ostringstream os; + os << " " << bt[i]; + log_writer->WriteLogMessage(fname_, line_, severity_, os.str().c_str()); + } + } + + abort(); +} + +Logger::~Logger() { + static const LogLevel min_log_level = MinLogLevelFromEnv(); + if (LogLevelPassThreashold(severity_, min_log_level)) { + GenerateLogMessage(); + } +} + +} // namespace port +} // namespace mace diff --git a/mace/port/logger.h b/mace/port/logger.h new file mode 100644 index 0000000000000000000000000000000000000000..08bcbbe4a8c3447332d897d602e05d9a38f6659e --- /dev/null +++ b/mace/port/logger.h @@ -0,0 +1,95 @@ +// Copyright 2019 The MACE Authors. 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. + +#ifndef MACE_PORT_LOGGER_H_ +#define MACE_PORT_LOGGER_H_ + +#include +#include +#include + +namespace mace { + +enum LogLevel { + INVALID_MIN = 0, + INFO = 1, + WARNING = 2, + ERROR = 3, + FATAL = 4, + INVALID_MAX, +}; + +namespace port { + +inline bool LogLevelPassThreashold(const LogLevel level, + const LogLevel threshold) { + return level >= threshold; +} + +LogLevel LogLevelFromStr(const char *log_level_str); +int VLogLevelFromStr(const char *vlog_level_str); + +inline LogLevel MinLogLevelFromEnv() { + // Read the min log level from env once during the first call to logging. + static LogLevel log_level = LogLevelFromStr(getenv("MACE_CPP_MIN_LOG_LEVEL")); + return log_level; +} + +inline int MinVLogLevelFromEnv() { + // Read the min vlog level from env once during the first call to logging. + static int vlog_level = VLogLevelFromStr(getenv("MACE_CPP_MIN_VLOG_LEVEL")); + return vlog_level; +} + +class LogWriter { + public: + LogWriter() = default; + virtual ~LogWriter() = default; + virtual void WriteLogMessage(const char *fname, + const int line, + const LogLevel severity, + const char *message); +}; + +class Logger : public std::ostringstream { + public: + Logger(const char *fname, int line, LogLevel severity); + ~Logger(); + + private: + void GenerateLogMessage(); + void DealWithFatal(); + + const char *fname_; + int line_; + LogLevel severity_; +}; + +} // namespace port + +// Whether the log level pass the env configured threshold, can be used for +// short cutting. +inline bool ShouldGenerateLogMessage(LogLevel severity) { + LogLevel threshold = port::MinLogLevelFromEnv(); + return port::LogLevelPassThreashold(severity, threshold); +} + +inline bool ShouldGenerateVLogMessage(int vlog_level) { + int threshold = port::MinVLogLevelFromEnv(); + return ShouldGenerateLogMessage(INFO) && + vlog_level <= threshold; +} +} // namespace mace + +#endif // MACE_PORT_LOGGER_H_ diff --git a/mace/port/logger_test.cc b/mace/port/logger_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..93df626ba8a2d61821dd68f07b3a3823fff8a5de --- /dev/null +++ b/mace/port/logger_test.cc @@ -0,0 +1,44 @@ +// Copyright 2019 The MACE Authors. 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 "mace/port/logger.h" + +#include + +namespace mace { +namespace { + +class LoggerTest : public ::testing::Test { +}; + +TEST_F(LoggerTest, LogLevel) { + EXPECT_EQ(INFO, port::LogLevelFromStr("i")); + EXPECT_EQ(INFO, port::LogLevelFromStr("I")); + EXPECT_EQ(INFO, port::LogLevelFromStr("INFO")); + + EXPECT_EQ(WARNING, port::LogLevelFromStr("w")); + EXPECT_EQ(WARNING, port::LogLevelFromStr("W")); + EXPECT_EQ(WARNING, port::LogLevelFromStr("WARNING")); + + EXPECT_EQ(ERROR, port::LogLevelFromStr("e")); + EXPECT_EQ(ERROR, port::LogLevelFromStr("E")); + EXPECT_EQ(ERROR, port::LogLevelFromStr("ERROR")); + + EXPECT_EQ(FATAL, port::LogLevelFromStr("f")); + EXPECT_EQ(FATAL, port::LogLevelFromStr("F")); + EXPECT_EQ(FATAL, port::LogLevelFromStr("FATAL")); +} + +} // namespace +} // namespace mace diff --git a/mace/port/posix/BUILD.bazel b/mace/port/posix/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..321a18a516d88749bde3e5cf2677fda941f12480 --- /dev/null +++ b/mace/port/posix/BUILD.bazel @@ -0,0 +1,19 @@ +package( + default_visibility = ["//visibility:public"], +) + +licenses(["notice"]) # Apache 2.0 + +cc_library( + name = "port_posix", + srcs = glob([ + "*.cc", + ]), + hdrs = glob([ + "*.h", + ]), + deps = [ + "//mace/port:port_base", + "//mace/utils", + ], +) diff --git a/mace/port/posix/backtrace.h b/mace/port/posix/backtrace.h new file mode 100644 index 0000000000000000000000000000000000000000..d96419319f874b34149a25493ca44ecd22680976 --- /dev/null +++ b/mace/port/posix/backtrace.h @@ -0,0 +1,45 @@ +// Copyright 2019 The MACE Authors. 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. + +#ifndef MACE_PORT_POSIX_BACKTRACE_H_ +#define MACE_PORT_POSIX_BACKTRACE_H_ + +#include + +#include +#include + +namespace mace { +namespace port { +namespace posix { + +inline std::vector GetBackTraceUnsafe(int max_steps) { + std::vector buffer(max_steps, 0); + int steps = backtrace(buffer.data(), max_steps); + + std::vector bt; + char **symbols = backtrace_symbols(buffer.data(), steps); + if (symbols != nullptr) { + for (int i = 0; i < steps; i++) { + bt.push_back(symbols[i]); + } + } + return bt; +} + +} // namespace posix +} // namespace port +} // namespace mace + +#endif // MACE_PORT_POSIX_BACKTRACE_H_ diff --git a/mace/port/posix/file_system.cc b/mace/port/posix/file_system.cc new file mode 100644 index 0000000000000000000000000000000000000000..236f221530c0d5d1be54dadf1c561f12edc6a560 --- /dev/null +++ b/mace/port/posix/file_system.cc @@ -0,0 +1,73 @@ +// Copyright 2019 The MACE Authors. 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 "mace/port/posix/file_system.h" + +#include +#include +#include +#include + +#include +#include + +#include "mace/utils/memory.h" + +namespace mace { +namespace port { + +namespace { +class PosixReadOnlyMemoryRegion : public ReadOnlyMemoryRegion { + public: + PosixReadOnlyMemoryRegion() = delete; + PosixReadOnlyMemoryRegion(const void* addr, uint64_t length) + : addr_(addr), length_(length) {} + ~PosixReadOnlyMemoryRegion() override { + munmap(const_cast(addr_), length_); + }; + const void *data() override { return addr_; }; + uint64_t length() override { return length_; }; + + private: + const void *addr_; + const uint64_t length_; +}; +} // namespace + +MaceStatus PosixFileSystem::NewReadOnlyMemoryRegionFromFile( + const char *fname, + std::unique_ptr* result) { + MaceStatus s = MaceStatus(MaceStatus::MACE_SUCCESS); + int fd = open(fname, O_RDONLY); + if (fd < 0) { + // TODO(heliangliang) check errno + s = MaceStatus(MaceStatus::MACE_RUNTIME_ERROR); + } else { + struct stat st; + fstat(fd, &st); + const void* address = + mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (address == MAP_FAILED) { + // TODO(heliangliang) check errno + s = MaceStatus(MaceStatus::MACE_RUNTIME_ERROR); + } else { + *result = make_unique(address, st.st_size); + } + close(fd); + } + return s; +} + +} // namespace port +} // namespace mace diff --git a/mace/port/posix/file_system.h b/mace/port/posix/file_system.h new file mode 100644 index 0000000000000000000000000000000000000000..8eb370757fcce9a558b993ac7f80e2d0ca1d2024 --- /dev/null +++ b/mace/port/posix/file_system.h @@ -0,0 +1,37 @@ +// Copyright 2019 The MACE Authors. 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. + +#ifndef MACE_PORT_POSIX_FILE_SYSTEM_H_ +#define MACE_PORT_POSIX_FILE_SYSTEM_H_ + +#include +#include + +#include "mace/port/file_system.h" + +namespace mace { +namespace port { + +class PosixFileSystem : public FileSystem { + public: + PosixFileSystem() = default; + ~PosixFileSystem() override = default; + MaceStatus NewReadOnlyMemoryRegionFromFile(const char *fname, + std::unique_ptr* result) override; +}; + +} // namespace port +} // namespace mace + +#endif // MACE_PORT_POSIX_FILE_SYSTEM_H_ diff --git a/mace/utils/env_time.h b/mace/port/posix/time.h similarity index 72% rename from mace/utils/env_time.h rename to mace/port/posix/time.h index 18d6e5a6ad6229284a2ae2e3e2fbbeb50fc952d7..84ab478a9580ad67618d53517a8f87afc4f2699b 100644 --- a/mace/utils/env_time.h +++ b/mace/port/posix/time.h @@ -1,4 +1,4 @@ -// Copyright 2018 The MACE Authors. All Rights Reserved. +// Copyright 2019 The MACE Authors. 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. @@ -12,28 +12,25 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef MACE_UTILS_ENV_TIME_H_ -#define MACE_UTILS_ENV_TIME_H_ +#ifndef MACE_PORT_POSIX_TIME_H_ +#define MACE_PORT_POSIX_TIME_H_ -#include -#ifdef __hexagon__ -#include -#else #include -#endif + +#include namespace mace { +namespace port { +namespace posix { inline int64_t NowMicros() { -#ifdef __hexagon__ - return HAP_perf_get_time_us(); -#else struct timeval tv; gettimeofday(&tv, nullptr); return static_cast(tv.tv_sec) * 1000000 + tv.tv_usec; -#endif } +} // namespace posix +} // namespace port } // namespace mace -#endif // MACE_UTILS_ENV_TIME_H_ +#endif // MACE_PORT_POSIX_TIME_H_ diff --git a/mace/proto/BUILD b/mace/proto/BUILD.bazel similarity index 100% rename from mace/proto/BUILD rename to mace/proto/BUILD.bazel diff --git a/mace/public/BUILD b/mace/public/BUILD.bazel similarity index 87% rename from mace/public/BUILD rename to mace/public/BUILD.bazel index b434312bcfdd4ec65a78bfc879a2dfcb41cc129c..158bc564dff7c4118ff368d0dfd1cb6a0eb0547f 100644 --- a/mace/public/BUILD +++ b/mace/public/BUILD.bazel @@ -12,5 +12,8 @@ cc_library( hdrs = [ "mace.h", ], + srcs = [ + "status.cc", + ], copts = ["-Werror", "-Wextra", "-Wno-missing-field-initializers"], ) diff --git a/mace/public/mace.h b/mace/public/mace.h index d71ecc1b4d0935958465ea37507a2ac32524c280..3d210d3801bd899a5ad27951f61a898648845096 100644 --- a/mace/public/mace.h +++ b/mace/public/mace.h @@ -144,7 +144,9 @@ class MaceStatus { enum Code { MACE_SUCCESS = 0, MACE_INVALID_ARGS = 1, - MACE_OUT_OF_RESOURCES = 2 + MACE_OUT_OF_RESOURCES = 2, + MACE_UNSUPPORTED = 3, + MACE_RUNTIME_ERROR = 4, }; public: @@ -167,18 +169,6 @@ class MaceStatus { std::unique_ptr impl_; }; - -#define MACE_RETURN_IF_ERROR(stmt) \ - { \ - MaceStatus status = (stmt); \ - if (status != MaceStatus::MACE_SUCCESS) { \ - VLOG(0) << "Mace runtime failure: " \ - << __FILE__ << ":" << __LINE__ << ". " \ - << status.information(); \ - return status; \ - } \ - } - /// \brief GPU context contain the status used for GPU device. /// /// There are some data in common between different MaceEngines using GPU, diff --git a/mace/core/status.cc b/mace/public/status.cc similarity index 86% rename from mace/core/status.cc rename to mace/public/status.cc index 12134f88a73940e26c8eb6c70a65011dcb25d647..c377c9b64112750bd9e46f53bdccf664b1aa8ca3 100644 --- a/mace/core/status.cc +++ b/mace/public/status.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + #include "mace/public/mace.h" namespace mace { @@ -26,10 +28,16 @@ class MaceStatus::Impl { void SetCode(const Code code) { code_ = code; } Code code() const { return code_; } void SetInformation(const std::string &info) { information_ = info; } - std::string information() const { return Code2Str() + ": " + information_; } + std::string information() const { + if (information_.empty()) { + return CodeToString(); + } else { + return CodeToString() + ": " + information_; + } + } private: - std::string Code2Str() const { + std::string CodeToString() const { switch (code_) { case MaceStatus::MACE_SUCCESS: return "Success"; @@ -37,8 +45,14 @@ class MaceStatus::Impl { return "Invalid Arguments"; case MaceStatus::MACE_OUT_OF_RESOURCES: return "Out of resources"; + case MACE_UNSUPPORTED: + return "Unsupported"; + case MACE_RUNTIME_ERROR: + return "Runtime error"; default: - return ""; + std::ostringstream os; + os << code_; + return os.str(); } } diff --git a/mace/python/tools/BUILD b/mace/python/tools/BUILD.bazel similarity index 100% rename from mace/python/tools/BUILD rename to mace/python/tools/BUILD.bazel diff --git a/mace/python/tools/model.jinja2 b/mace/python/tools/model.jinja2 index 1beae21ab41ca1fc583fbd016b4e6d8430ad2ff9..c7d936c0318527423e8b251b06647048c446a17a 100644 --- a/mace/python/tools/model.jinja2 +++ b/mace/python/tools/model.jinja2 @@ -16,10 +16,10 @@ #include -#include "mace/core/macros.h" +#include "mace/utils/macros.h" #include "mace/proto/mace.pb.h" #include "mace/public/mace.h" -#include "mace/utils/env_time.h" +#include "mace/port/env.h" #include "mace/utils/logging.h" namespace mace { diff --git a/mace/python/tools/operator.jinja2 b/mace/python/tools/operator.jinja2 index 8992da31ef7c9468b723d362ac04ab98511593f5..b184b54a3d98f034147866d04a6b48c1af0703f9 100644 --- a/mace/python/tools/operator.jinja2 +++ b/mace/python/tools/operator.jinja2 @@ -19,7 +19,7 @@ #include "mace/proto/mace.pb.h" #include "mace/public/mace.h" -#include "mace/utils/env_time.h" +#include "mace/port/env.h" #include "mace/utils/logging.h" namespace mace { diff --git a/mace/python/tools/tensor_source.jinja2 b/mace/python/tools/tensor_source.jinja2 index 77d91eab6aff431549b8e848369503944d52d5d3..d459d9bc806d23f7cb49ad90ba72f2a753dfd886 100644 --- a/mace/python/tools/tensor_source.jinja2 +++ b/mace/python/tools/tensor_source.jinja2 @@ -16,7 +16,7 @@ #include "mace/proto/mace.pb.h" #include "mace/public/mace.h" -#include "mace/utils/env_time.h" +#include "mace/port/env.h" #include "mace/utils/logging.h" namespace mace { diff --git a/mace/python/tools/visualization/BUILD b/mace/python/tools/visualization/BUILD.bazel similarity index 100% rename from mace/python/tools/visualization/BUILD rename to mace/python/tools/visualization/BUILD.bazel diff --git a/mace/test/BUILD b/mace/test/BUILD.bazel similarity index 100% rename from mace/test/BUILD rename to mace/test/BUILD.bazel diff --git a/mace/tools/validation/BUILD b/mace/tools/validation/BUILD.bazel similarity index 100% rename from mace/tools/validation/BUILD rename to mace/tools/validation/BUILD.bazel diff --git a/mace/tools/validation/mace_run.cc b/mace/tools/validation/mace_run.cc index 947255e5cbd9af8a3f064277ee38b0fd3d3c510c..d7a911a07f8073e2ea907e58f182af96128637ef 100644 --- a/mace/tools/validation/mace_run.cc +++ b/mace/tools/validation/mace_run.cc @@ -24,8 +24,7 @@ * --model_data_file=model_data.data \ * --device=GPU */ -#include -#include +#include #include #include #include @@ -34,9 +33,9 @@ #include "gflags/gflags.h" #include "mace/public/mace.h" -#include "mace/utils/env_time.h" +#include "mace/port/env.h" #include "mace/utils/logging.h" -#include "mace/utils/utils.h" +#include "mace/utils/string_util.h" #ifdef MODEL_GRAPH_FORMAT_CODE #include "mace/codegen/engine/mace_engine_factory.h" @@ -46,29 +45,6 @@ namespace mace { namespace tools { namespace validation { -namespace str_util { - -std::vector Split(const std::string &str, char delims) { - std::vector result; - if (str.empty()) { - result.push_back(""); - return result; - } - std::string tmp = str; - while (!tmp.empty()) { - size_t next_offset = tmp.find(delims); - result.push_back(tmp.substr(0, next_offset)); - if (next_offset == std::string::npos) { - break; - } else { - tmp = tmp.substr(next_offset + 1); - } - } - return result; -} - -} // namespace str_util - void ParseShape(const std::string &str, std::vector *shape) { std::string tmp = str; while (!tmp.empty()) { @@ -500,13 +476,10 @@ int Main(int argc, char **argv) { LOG(INFO) << "omp_num_threads: " << FLAGS_omp_num_threads; LOG(INFO) << "cpu_affinity_policy: " << FLAGS_cpu_affinity_policy; - std::vector input_names = str_util::Split(FLAGS_input_node, ','); - std::vector output_names = - str_util::Split(FLAGS_output_node, ','); - std::vector input_shapes = - str_util::Split(FLAGS_input_shape, ':'); - std::vector output_shapes = - str_util::Split(FLAGS_output_shape, ':'); + std::vector input_names = Split(FLAGS_input_node, ','); + std::vector output_names = Split(FLAGS_output_node, ','); + std::vector input_shapes = Split(FLAGS_input_shape, ':'); + std::vector output_shapes = Split(FLAGS_output_shape, ':'); const size_t input_count = input_shapes.size(); const size_t output_count = output_shapes.size(); diff --git a/mace/utils/BUILD b/mace/utils/BUILD.bazel similarity index 61% rename from mace/utils/BUILD rename to mace/utils/BUILD.bazel index 4388e1a6628de7f738cb2a971d9a9c8f29022bd3..56b794378da9ad53716cb5c52753f44b231373f7 100644 --- a/mace/utils/BUILD +++ b/mace/utils/BUILD.bazel @@ -7,12 +7,6 @@ package( licenses(["notice"]) # Apache 2.0 -load( - "//mace:mace.bzl", - "if_android", - "if_openmp_enabled", -) - cc_library( name = "utils", srcs = glob( @@ -20,7 +14,7 @@ cc_library( "*.cc", ], exclude = [ - "tuner_test.cc", + "*_test.cc", ], ), hdrs = glob([ @@ -30,36 +24,30 @@ cc_library( "-Werror", "-Wextra", "-Wno-missing-field-initializers", - ] + if_openmp_enabled([ - "-fopenmp", - ]), - linkopts = if_android([ - "-llog", - ]), + ], deps = [ + "//mace/port:port_api", "//mace/public", ], ) cc_test( - name = "tuner_test", + name = "utils_test", testonly = 1, - srcs = [ - "tuner_test.cc", - ], + srcs = glob( + [ + "*_test.cc", + ], + ), copts = [ "-Werror", "-Wextra", "-Wno-missing-field-initializers", ], - linkopts = ["-ldl"] + if_android([ - "-pie", - "-lm", # Required by unordered_map - ]), - linkstatic = 1, + linkstatic = 0, deps = [ ":utils", - "//mace/core", + "//mace/port", "@gtest//:gtest", "@gtest//:gtest_main", ], diff --git a/mace/utils/conf_util.h b/mace/utils/conf_util.h new file mode 100644 index 0000000000000000000000000000000000000000..4800b15e24d47c3690531a94f52214616c710624 --- /dev/null +++ b/mace/utils/conf_util.h @@ -0,0 +1,33 @@ +// Copyright 2018 The MACE Authors. 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. + +#ifndef MACE_UTILS_CONF_UTIL_H_ +#define MACE_UTILS_CONF_UTIL_H_ + +#include +#include +#include +#include +#include + +namespace mace { + +inline bool EnvConfEnabled(std::string env_name) { + char *env = getenv(env_name.c_str()); + return !(!env || env[0] == 0 || env[0] == '0'); +} + +} // namespace mace + +#endif // MACE_UTILS_CONF_UTIL_H_ diff --git a/mace/utils/detection_output.cc b/mace/utils/detection_output.cc deleted file mode 100644 index 10a4f4f0903e65d3d11ff53051b61f4a15dc1756..0000000000000000000000000000000000000000 --- a/mace/utils/detection_output.cc +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2018 The MACE Authors. 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 -#include -#include -#include -#include -#include - -#include "mace/utils/logging.h" - -namespace mace { - -struct BBox { - float xmin; - float ymin; - float xmax; - float ymax; - int label; - float confidence; -}; - -namespace { -inline float overlap(const BBox &a, const BBox &b) { - if (a.xmin > b.xmax || a.xmax < b.xmin || - a.ymin > b.ymax || a.ymax < b.ymin) { - return 0.f; - } - float overlap_w = std::min(a.xmax, b.xmax) - std::max(a.xmin, b.xmin); - float overlap_h = std::min(a.ymax, b.ymax) - std::max(a.ymin, b.ymin); - return overlap_w * overlap_h; -} - -void NmsSortedBboxes(const std::vector &bboxes, - const float nms_threshold, - const int top_k, - std::vector *sorted_boxes) { - const int n = std::min(top_k, static_cast(bboxes.size())); - std::vector picked; - - std::vector areas(n); -#pragma omp parallel for schedule(runtime) - for (int i = 0; i < n; ++i) { - const BBox &r = bboxes[i]; - float width = std::max(0.f, r.xmax - r.xmin); - float height = std::max(0.f, r.ymax - r.ymin); - areas[i] = width * height; - } - - for (int i = 0; i < n; ++i) { - const BBox &a = bboxes[i]; - int keep = 1; - for (size_t j = 0; j < picked.size(); ++j) { - const BBox &b = bboxes[picked[j]]; - - float inter_area = overlap(a, b); - float union_area = areas[i] + areas[picked[j]] - inter_area; - MACE_CHECK(union_area > 0, "union_area should be greater than 0"); - if (inter_area / union_area > nms_threshold) { - keep = 0; - break; - } - } - - if (keep) { - picked.push_back(i); - sorted_boxes->push_back(bboxes[i]); - } - } -} - -inline bool cmp(const BBox &a, const BBox &b) { - return a.confidence > b.confidence; -} -} // namespace - -int DetectionOutput(const float *loc_ptr, - const float *conf_ptr, - const float *pbox_ptr, - const int num_prior, - const int num_classes, - const float nms_threshold, - const int top_k, - const int keep_top_k, - const float confidence_threshold, - std::vector *bbox_rects) { - MACE_CHECK(keep_top_k > 0, "keep_top_k should be greater than 0"); - std::vector bboxes(4 * num_prior); -#pragma omp parallel for schedule(runtime) - for (int i = 0; i < num_prior; ++i) { - int index = i * 4; - const float *lc = loc_ptr + index; - const float *pb = pbox_ptr + index; - const float *var = pb + num_prior * 4; - - float pb_w = pb[2] - pb[0]; - float pb_h = pb[3] - pb[1]; - float pb_cx = (pb[0] + pb[2]) * 0.5f; - float pb_cy = (pb[1] + pb[3]) * 0.5f; - - float bbox_cx = var[0] * lc[0] * pb_w + pb_cx; - float bbox_cy = var[1] * lc[1] * pb_h + pb_cy; - float bbox_w = std::exp(var[2] * lc[2]) * pb_w; - float bbox_h = std::exp(var[3] * lc[3]) * pb_h; - - bboxes[0 + index] = bbox_cx - bbox_w * 0.5f; - bboxes[1 + index] = bbox_cy - bbox_h * 0.5f; - bboxes[2 + index] = bbox_cx + bbox_w * 0.5f; - bboxes[3 + index] = bbox_cy + bbox_h * 0.5f; - } - // start from 1 to ignore background class - - for (int i = 1; i < num_classes; ++i) { - // filter by confidence threshold - std::vector class_bbox_rects; - for (int j = 0; j < num_prior; ++j) { - float confidence = conf_ptr[j * num_classes + i]; - if (confidence > confidence_threshold) { - BBox c = {bboxes[0 + j * 4], bboxes[1 + j * 4], bboxes[2 + j * 4], - bboxes[3 + j * 4], i, confidence}; - class_bbox_rects.push_back(c); - } - } - std::sort(class_bbox_rects.begin(), class_bbox_rects.end(), cmp); - - // apply nms - std::vector sorted_boxes; - NmsSortedBboxes(class_bbox_rects, - nms_threshold, - std::min(top_k, - static_cast(class_bbox_rects.size())), - &sorted_boxes); - // gather - bbox_rects->insert(bbox_rects->end(), sorted_boxes.begin(), - sorted_boxes.end()); - } - - std::sort(bbox_rects->begin(), bbox_rects->end(), cmp); - - // output - int num_detected = keep_top_k < static_cast(bbox_rects->size()) ? - keep_top_k : static_cast(bbox_rects->size()); - bbox_rects->resize(num_detected); - - return num_detected; -} -} // namespace mace diff --git a/mace/utils/logging.cc b/mace/utils/logging.cc deleted file mode 100644 index 8091f0a0148e8f1d68f7c88858585d51f232dd8a..0000000000000000000000000000000000000000 --- a/mace/utils/logging.cc +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2018 The MACE Authors. 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 "mace/utils/logging.h" - -#include -#include -#include -#if defined(ANDROID) || defined(__ANDROID__) -#include -#include -#endif - -namespace mace { -namespace logging { - -LogMessage::LogMessage(const char *fname, int line, int severity) - : fname_(fname), line_(line), severity_(severity) {} - -void LogMessage::DealWithFatal() { - // When there is a fatal log, now we simply abort. - abort(); -} - -void LogMessage::GenerateLogMessage() { -#if defined(ANDROID) || defined(__ANDROID__) - int android_log_level; - switch (severity_) { - case INFO: - android_log_level = ANDROID_LOG_INFO; - break; - case WARNING: - android_log_level = ANDROID_LOG_WARN; - break; - case ERROR: - android_log_level = ANDROID_LOG_ERROR; - break; - case FATAL: - android_log_level = ANDROID_LOG_FATAL; - break; - default: - if (severity_ < INFO) { - android_log_level = ANDROID_LOG_VERBOSE; - } else { - android_log_level = ANDROID_LOG_ERROR; - } - break; - } - - std::stringstream ss; - const char *const partial_name = strrchr(fname_, '/'); - ss << (partial_name != nullptr ? partial_name + 1 : fname_) << ":" << line_ - << " " << str(); - __android_log_write(android_log_level, "MACE", ss.str().c_str()); - - // Also log to stderr (for standalone Android apps). - std::cerr << "IWEF"[severity_] << " " << ss.str() << std::endl; -#else - fprintf(stderr, "%c %s:%d] %s\n", "IWEF"[severity_], fname_, line_, - str().c_str()); -#endif - - // When there is a fatal log, terminate execution - if (severity_ == FATAL) { - DealWithFatal(); - } -} -namespace { - -int LogLevelStrToInt(const char *mace_env_var_val) { - if (mace_env_var_val == nullptr) { - return 0; - } - // Simply use atoi here. Return 0 if convert unsuccessfully. - return atoi(mace_env_var_val); -} - -int MinLogLevelFromEnv() { - // Read the min log level from env once during the first call to logging. - static int log_level = LogLevelStrToInt(getenv("MACE_CPP_MIN_LOG_LEVEL")); - return log_level; -} - -int MinVLogLevelFromEnv() { - // Read the min vlog level from env once during the first call to logging. - static int vlog_level = LogLevelStrToInt(getenv("MACE_CPP_MIN_VLOG_LEVEL")); - return vlog_level; -} - -} // namespace - -LogMessage::~LogMessage() { - int min_log_level = MinLogLevelFromEnv(); - if (severity_ >= min_log_level) GenerateLogMessage(); -} - -int LogMessage::MinVLogLevel() { - return MinVLogLevelFromEnv(); -} - -} // namespace logging -} // namespace mace diff --git a/mace/utils/logging.h b/mace/utils/logging.h index 63d372d88b5c1241e34f8c92c7ff9b7c41d6a33e..8a5f2f8e025f1ad350a9503243dd66ad9628691f 100644 --- a/mace/utils/logging.h +++ b/mace/utils/logging.h @@ -1,4 +1,4 @@ -// Copyright 2018 The MACE Authors. All Rights Reserved. +// Copyright 2019 The MACE Authors. 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. @@ -21,45 +21,19 @@ #include #include -#include "mace/public/mace.h" -#include "mace/utils/env_time.h" +#include "mace/port/env.h" +#include "mace/port/logger.h" +#include "mace/utils/macros.h" #include "mace/utils/string_util.h" -#include "mace/utils/utils.h" -#undef ERROR namespace mace { - -// Log severity level constants. -const int INFO = 0; -const int WARNING = 1; -const int ERROR = 2; -const int FATAL = 3; - -namespace logging { - -class LogMessage : public std::ostringstream { - public: - LogMessage(const char *fname, int line, int severity); - ~LogMessage(); - - static int MinVLogLevel(); - - private: - void GenerateLogMessage(); - void DealWithFatal(); - - const char *fname_; - int line_; - int severity_; -}; +namespace logging_internal { #define LOG(severity) \ - ::mace::logging::LogMessage(__FILE__, __LINE__, mace::severity) + ::mace::port::Logger(__FILE__, __LINE__, mace::severity) -// Set MACE_CPP_MIN_VLOG_LEVEL environment to update minimum log level of VLOG. -// Only when vlog_level <= MinVLogLevel(), it will produce output. -#define VLOG_IS_ON(vll) ((vll) <= ::mace::logging::LogMessage::MinVLogLevel()) +#define VLOG_IS_ON(vll) (mace::ShouldGenerateVLogMessage(vll)) #define VLOG(vll) if (VLOG_IS_ON(vll)) LOG(INFO) // MACE_CHECK/MACE_ASSERT dies with a fatal error if condition is not true. @@ -85,17 +59,27 @@ class LogMessage : public std::ostringstream { template T &&CheckNotNull(const char *file, int line, const char *exprtext, T &&t) { if (t == nullptr) { - ::mace::logging::LogMessage(file, line, FATAL) << std::string(exprtext); + ::mace::port::Logger(file, line, FATAL) << std::string(exprtext); } return std::forward(t); } #define MACE_CHECK_NOTNULL(val) \ - ::mace::logging::CheckNotNull(__FILE__, __LINE__, \ - "'" #val "' Must not be NULL", (val)) + ::mace::logging_internal::CheckNotNull(__FILE__, __LINE__, \ + "'" #val "' Must not be NULL", (val)) #define MACE_NOT_IMPLEMENTED MACE_CHECK(false, "not implemented") +#define MACE_RETURN_IF_ERROR(stmt) \ + { \ + MaceStatus status = (stmt); \ + if (status != MaceStatus::MACE_SUCCESS) { \ + VLOG(0) << #stmt << " failed with error: " \ + << status.information(); \ + return status; \ + } \ + } + class LatencyLogger { public: LatencyLogger(int vlog_level, const std::string &message) @@ -121,11 +105,21 @@ class LatencyLogger { MACE_DISABLE_COPY_AND_ASSIGN(LatencyLogger); }; -#define MACE_LATENCY_LOGGER(vlog_level, ...) \ - mace::logging::LatencyLogger latency_logger_##__line__( \ +#define MACE_LATENCY_LOGGER(vlog_level, ...) \ + mace::logging_internal::LatencyLogger latency_logger_##__line__( \ vlog_level, VLOG_IS_ON(vlog_level) ? mace::MakeString(__VA_ARGS__) : "") -} // namespace logging + +#ifdef MACE_ENABLE_MALLOC_LOGGING +#define MACE_MEMORY_LOGGING_GUARD() \ + auto malloc_logger_##__line__ = port::Env::Default()->NewMallocLogger( \ + ::mace::port::Logger(__FILE__, __LINE__, mace::INFO), \ + std::string(__FILE__) + ":" + std::string(__func__)); +#else +#define MACE_MEMORY_LOGGING_GUARD() +#endif + +} // namespace logging_internal } // namespace mace #endif // MACE_UTILS_LOGGING_H_ diff --git a/mace/utils/logging_test.cc b/mace/utils/logging_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..88cee53dbebcb35cfabb12918565ea290cbd46c0 --- /dev/null +++ b/mace/utils/logging_test.cc @@ -0,0 +1,43 @@ +// Copyright 2019 The MACE Authors. 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 "mace/utils/logging.h" + +#include + +namespace mace { +namespace { + +class LoggingTest : public ::testing::Test { +}; + +TEST_F(LoggingTest, Basic) { + LOG(INFO) << "info logging"; + LOG(WARNING) << "warning logging"; + LOG(ERROR) << "error logging"; + + VLOG(1) << "vlog 1 logging"; + VLOG(2) << "vlog 2 logging"; + + if (VLOG_IS_ON(1)) { + VLOG(1) << "vlog 1 logging"; + } +} + +TEST_F(LoggingTest, LogFatal) { + EXPECT_DEATH(do { LOG(FATAL) << "fatal logging"; } while (false), ""); +} + +} // namespace +} // namespace mace diff --git a/mace/core/macros.h b/mace/utils/macros.h similarity index 61% rename from mace/core/macros.h rename to mace/utils/macros.h index e90049f4764ea07654ed810e8086230dc2fc9b5b..1ce38183018b5ddb9b64a3756126cfd6426c4f68 100644 --- a/mace/core/macros.h +++ b/mace/utils/macros.h @@ -1,4 +1,4 @@ -// Copyright 2018 The MACE Authors. All Rights Reserved. +// Copyright 2019 The MACE Authors. 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. @@ -12,8 +12,27 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef MACE_CORE_MACROS_H_ -#define MACE_CORE_MACROS_H_ +#ifndef MACE_UTILS_MACROS_H_ +#define MACE_UTILS_MACROS_H_ + +namespace mace { + +// Disable the copy and assignment operator for a class. +#ifndef MACE_DISABLE_COPY_AND_ASSIGN +#define MACE_DISABLE_COPY_AND_ASSIGN(CLASSNAME) \ + CLASSNAME(const CLASSNAME &) = delete; \ + CLASSNAME &operator=(const CLASSNAME &) = delete; +#endif + +#ifndef MACE_EMPTY_VIRTUAL_DESTRUCTOR +#define MACE_EMPTY_VIRTUAL_DESTRUCTOR(CLASSNAME) \ + public: \ + virtual ~CLASSNAME() {} +#endif + +#define MACE_UNUSED(var) (void)(var) + +#define MACE_COMPUTE_KERNEL_SOURCE(...) #__VA_ARGS__ // GCC can be told that a certain branch is not likely to be taken (for // instance, a CHECK failure), and use that information in static analysis. @@ -27,6 +46,6 @@ #define MACE_PREDICT_TRUE(x) (x) #endif -#define MACE_UNUSED(var) (void)(var) +} // namespace mace -#endif // MACE_CORE_MACROS_H_ +#endif // MACE_UTILS_MACROS_H_ diff --git a/mace/utils/utils.h b/mace/utils/math.h similarity index 58% rename from mace/utils/utils.h rename to mace/utils/math.h index 7ebdd22126a2e4e1a360a6f012fea9d8fb982d44..0293806c66667d55439b6802e1a8ec3943c1635e 100644 --- a/mace/utils/utils.h +++ b/mace/utils/math.h @@ -12,31 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef MACE_UTILS_UTILS_H_ -#define MACE_UTILS_UTILS_H_ +#ifndef MACE_UTILS_MATH_H_ +#define MACE_UTILS_MATH_H_ -#include -#include #include -#include -#include -#include -namespace mace { +#include +#include -// Disable the copy and assignment operator for a class. -#ifndef MACE_DISABLE_COPY_AND_ASSIGN -#define MACE_DISABLE_COPY_AND_ASSIGN(CLASSNAME) \ - private: \ - CLASSNAME(const CLASSNAME &) = delete; \ - CLASSNAME &operator=(const CLASSNAME &) = delete -#endif +#include "mace/utils/logging.h" -#ifndef MACE_EMPTY_VIRTUAL_DESTRUCTOR -#define MACE_EMPTY_VIRTUAL_DESTRUCTOR(CLASSNAME) \ - public: \ - virtual ~CLASSNAME() {} -#endif +namespace mace { template Integer RoundUp(Integer i, Integer factor) { @@ -69,8 +55,6 @@ Integer CeilQuotient(Integer a, Integer b) { return (a + b - 1) / b; } -std::string ObfuscateString(const std::string &src, - const std::string &lookup_table); template inline Integer Clamp(Integer in, Integer low, Integer high) { return std::max(low, std::min(in, high)); @@ -98,48 +82,11 @@ inline T ScalarTanh(T in) { } } -std::string ObfuscateString(const std::string &src); - -std::string ObfuscateSymbol(const std::string &src); - -#ifdef MACE_OBFUSCATE_LITERALS -#define MACE_OBFUSCATE_STRING(str) ObfuscateString(str) -#define MACE_OBFUSCATE_SYMBOL(str) ObfuscateSymbol(str) -#else -#define MACE_OBFUSCATE_STRING(str) (str) -#define MACE_OBFUSCATE_SYMBOL(str) (str) -#endif - -std::vector Split(const std::string &str, char delims); - -bool ReadBinaryFile(std::vector *data, - const std::string &filename); - -void MemoryMap(const std::string &file, - const unsigned char **data, - size_t *size); - -void MemoryUnMap(const unsigned char *data, - const size_t &size); - -template -std::vector MapKeys(const std::map &data) { - std::vector keys; - for (auto &kv : data) { - keys.push_back(kv.first); - } - return keys; -} - -inline bool EnvEnabled(std::string env_name) { - char *env = getenv(env_name.c_str()); - return !(!env || env[0] == 0 || env[0] == '0'); -} - template std::vector TransposeShape(const std::vector &shape, const std::vector &dst_dims) { size_t shape_dims = shape.size(); + MACE_CHECK(shape_dims == dst_dims.size()); std::vector output_shape(shape_dims); for (size_t i = 0; i < shape_dims; ++i) { output_shape[i] = static_cast(shape[dst_dims[i]]); @@ -148,4 +95,5 @@ std::vector TransposeShape(const std::vector &shape, } } // namespace mace -#endif // MACE_UTILS_UTILS_H_ + +#endif // MACE_UTILS_MATH_H_ diff --git a/mace/utils/memory_logging.h b/mace/utils/memory_logging.h deleted file mode 100644 index 4e3cd5883b749b8f1d49d5f8d6ec886d8f65a78b..0000000000000000000000000000000000000000 --- a/mace/utils/memory_logging.h +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2018 The MACE Authors. 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. - -#ifndef MACE_UTILS_MEMORY_LOGGING_H_ -#define MACE_UTILS_MEMORY_LOGGING_H_ - -#ifndef __hexagon__ -#include -#endif -#include - -#include "mace/utils/logging.h" - -namespace mace { - -#ifdef MACE_ENABLE_MEMORY_LOGGING -class MallinfoChangeLogger { - public: - explicit MallinfoChangeLogger(const std::string &name) : name_(name) { - prev_ = mallinfo(); - } - ~MallinfoChangeLogger() { - struct mallinfo curr = mallinfo(); - LogMallinfoChange(name_, curr, prev_); - } - - private: - const std::string name_; - struct mallinfo prev_; - - struct mallinfo LogMallinfoChange(const std::string &name, - const struct mallinfo curr, - const struct mallinfo prev) { - if (prev.arena != curr.arena) { - LOG(INFO) << "[" << name << "] " - << "Non-mmapped space allocated (bytes): " << curr.arena - << ", diff: " << ((int64_t)curr.arena - (int64_t)prev.arena); - } - if (prev.ordblks != curr.ordblks) { - LOG(INFO) << "[" << name << "] " - << "Number of free chunks: " << curr.ordblks << ", diff: " - << ((int64_t)curr.ordblks - (int64_t)prev.ordblks); - } - if (prev.smblks != curr.smblks) { - LOG(INFO) << "[" << name << "] " - << "Number of free fastbin blocks: " << curr.smblks - << ", diff: " << ((int64_t)curr.smblks - (int64_t)prev.smblks); - } - if (prev.hblks != curr.hblks) { - LOG(INFO) << "[" << name << "] " - << "Number of mmapped regions: " << curr.hblks - << ", diff: " << ((int64_t)curr.hblks - (int64_t)prev.hblks); - } - if (prev.hblkhd != curr.hblkhd) { - LOG(INFO) << "[" << name << "] " - << "Space allocated in mmapped regions (bytes): " << curr.hblkhd - << ", diff: " << ((int64_t)curr.hblkhd - (int64_t)prev.hblkhd); - } - if (prev.usmblks != curr.usmblks) { - LOG(INFO) << "[" << name << "] " - << "Maximum total allocated space (bytes): " << curr.usmblks - << ", diff: " - << ((int64_t)curr.usmblks - (int64_t)prev.usmblks); - } - if (prev.fsmblks != curr.fsmblks) { - LOG(INFO) << "[" << name << "] " - << "Space in freed fastbin blocks (bytes): " << curr.fsmblks - << ", diff: " - << ((int64_t)curr.fsmblks - (int64_t)prev.fsmblks); - } - if (prev.uordblks != curr.uordblks) { - LOG(INFO) << "[" << name << "] " - << "Total allocated space (bytes): " << curr.uordblks - << ", diff: " - << ((int64_t)curr.uordblks - (int64_t)prev.uordblks); - } - if (prev.fordblks != curr.fordblks) { - LOG(INFO) << "[" << name << "] " - << "Total free space (bytes): " << curr.fordblks << ", diff: " - << ((int64_t)curr.fordblks - (int64_t)prev.fordblks); - } - if (prev.keepcost != curr.keepcost) { - LOG(INFO) << "[" << name << "] " - << "Top-most, releasable space (bytes): " << curr.keepcost - << ", diff: " - << ((int64_t)curr.keepcost - (int64_t)prev.keepcost); - } - return curr; - } -}; - -#define MACE_MEMORY_LOGGING_GUARD() \ - MallinfoChangeLogger mem_logger_##__line__(std::string(__FILE__) + ":" + \ - std::string(__func__)); -#else -#define MACE_MEMORY_LOGGING_GUARD() -#endif - -} // namespace mace - -#endif // MACE_UTILS_MEMORY_LOGGING_H_ diff --git a/mace/utils/rwlock.h b/mace/utils/rwlock.h index c15fa5ad7a605ce1dc0d7b2fabb083a4aba53e7f..b4d6392ce3772fac468b46f450faa89839c8e5f6 100644 --- a/mace/utils/rwlock.h +++ b/mace/utils/rwlock.h @@ -17,7 +17,9 @@ #include // NOLINT(build/c++11) #include // NOLINT(build/c++11) + #include "mace/utils/logging.h" +#include "mace/utils/macros.h" namespace mace { namespace utils { @@ -26,10 +28,6 @@ class RWMutex { public: RWMutex() : counter_(0), waiting_readers_(0), waiting_writers_(0) {} ~RWMutex() = default; - RWMutex(const RWMutex &) = delete; - RWMutex(RWMutex &&) = delete; - RWMutex& operator=(const RWMutex &) = delete; - RWMutex& operator=(RWMutex &&) = delete; int counter_; // -1 for writer, 0 for nobody, 1~n for reader int waiting_readers_; @@ -37,6 +35,8 @@ class RWMutex { std::mutex mutex_; std::condition_variable reader_cv_; std::condition_variable writer_cv_; + + MACE_DISABLE_COPY_AND_ASSIGN(RWMutex); }; // Writer first @@ -61,13 +61,11 @@ class ReadLock { } } } - ReadLock(const ReadLock &) = delete; - ReadLock(ReadLock &&) = delete; - ReadLock& operator=(const ReadLock &) = delete; - ReadLock& operator=(ReadLock &&) = delete; private: RWMutex *rw_mutex_; + + MACE_DISABLE_COPY_AND_ASSIGN(ReadLock); }; class WriteLock { @@ -91,13 +89,11 @@ class WriteLock { rw_mutex_->reader_cv_.notify_all(); } } - WriteLock(const WriteLock &) = delete; - WriteLock(WriteLock &&) = delete; - WriteLock& operator=(const WriteLock &) = delete; - WriteLock& operator=(WriteLock &&) = delete; private: RWMutex *rw_mutex_; + + MACE_DISABLE_COPY_AND_ASSIGN(WriteLock); }; } // namespace utils diff --git a/mace/utils/stl_util.h b/mace/utils/stl_util.h new file mode 100644 index 0000000000000000000000000000000000000000..44dd1d8e384b7bfa260e12b9f33183a5ec5b7157 --- /dev/null +++ b/mace/utils/stl_util.h @@ -0,0 +1,37 @@ +// Copyright 2018 The MACE Authors. 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. + +#ifndef MACE_UTILS_STL_UTIL_H_ +#define MACE_UTILS_STL_UTIL_H_ + +#include +#include +#include +#include +#include + +namespace mace { + +template +std::vector MapKeys(const std::map &data) { + std::vector keys; + for (auto &kv : data) { + keys.push_back(kv.first); + } + return keys; +} + +} // namespace mace + +#endif // MACE_UTILS_STL_UTIL_H_ diff --git a/mace/utils/string_util.cc b/mace/utils/string_util.cc index 3492706fe068f3caef8ce9443b505f887fb97ab6..8114e3aad7364c20a2d14b75912d1d798df24263 100644 --- a/mace/utils/string_util.cc +++ b/mace/utils/string_util.cc @@ -83,4 +83,65 @@ std::string StringFormatter::Table( } } // namespace string_util + +std::string ObfuscateString(const std::string &src, + const std::string &lookup_table) { + std::string dest; + dest.resize(src.size()); + for (size_t i = 0; i < src.size(); i++) { + dest[i] = src[i] ^ lookup_table[i % lookup_table.size()]; + } + return dest; +} + +// ObfuscateString(ObfuscateString(str)) ==> str +std::string ObfuscateString(const std::string &src) { + // Keep consistent with obfuscation in python tools + return ObfuscateString(src, "Mobile-AI-Compute-Engine"); +} + +// Obfuscate synbol or path string +std::string ObfuscateSymbol(const std::string &src) { + std::string dest = src; + if (dest.empty()) { + return dest; + } + dest[0] = src[0]; // avoid invalid symbol which starts from 0-9 + const std::string encode_dict = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; + for (size_t i = 1; i < src.size(); i++) { + char ch = src[i]; + int idx; + if (ch >= '0' && ch <= '9') { + idx = ch - '0'; + } else if (ch >= 'a' && ch <= 'z') { + idx = 10 + ch - 'a'; + } else if (ch >= 'A' && ch <= 'Z') { + idx = 10 + 26 + ch - 'a'; + } else if (ch == '_') { + idx = 10 + 26 + 26; + } else { + dest[i] = ch; + continue; + } + // There is no collision if it's true for every char at every position + dest[i] = encode_dict[(idx + i + 31) % encode_dict.size()]; + } + return dest; +} + +std::vector Split(const std::string &str, char delims) { + std::vector result; + std::string tmp = str; + while (!tmp.empty()) { + size_t next_offset = tmp.find(delims); + result.push_back(tmp.substr(0, next_offset)); + if (next_offset == std::string::npos) { + break; + } else { + tmp = tmp.substr(next_offset + 1); + } + } + return result; +} } // namespace mace diff --git a/mace/utils/string_util.h b/mace/utils/string_util.h index c41aaaa12fdb682bc7aea2d08076b867ad8615f0..c9df13566335b4041aca30d6a6f4e911434bb0d4 100644 --- a/mace/utils/string_util.h +++ b/mace/utils/string_util.h @@ -15,6 +15,7 @@ #ifndef MACE_UTILS_STRING_UTIL_H_ #define MACE_UTILS_STRING_UTIL_H_ +#include #include #include #include @@ -80,6 +81,35 @@ inline std::string MakeString(const std::string &str) { inline std::string MakeString(const char *c_str) { return std::string(c_str); } +inline std::string ToLower(const std::string &src) { + std::string dest(src); + std::transform(src.begin(), src.end(), dest.begin(), ::tolower); + return dest; +} + +inline std::string ToUpper(const std::string &src) { + std::string dest(src); + std::transform(src.begin(), src.end(), dest.begin(), ::toupper); + return dest; +} + +std::string ObfuscateString(const std::string &src, + const std::string &lookup_table); + +std::string ObfuscateString(const std::string &src); + +std::string ObfuscateSymbol(const std::string &src); + +#ifdef MACE_OBFUSCATE_LITERALS +#define MACE_OBFUSCATE_STRING(str) ObfuscateString(str) +#define MACE_OBFUSCATE_SYMBOL(str) ObfuscateSymbol(str) +#else +#define MACE_OBFUSCATE_STRING(str) (str) +#define MACE_OBFUSCATE_SYMBOL(str) (str) +#endif + +std::vector Split(const std::string &str, char delims); + } // namespace mace #endif // MACE_UTILS_STRING_UTIL_H_ diff --git a/mace/utils/string_util_test.cc b/mace/utils/string_util_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..84b9b0a671a5655d3f9660e859d5ff0ed56b9f3a --- /dev/null +++ b/mace/utils/string_util_test.cc @@ -0,0 +1,40 @@ +// Copyright 2019 The MACE Authors. 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 "mace/utils/string_util.h" + +#include + +namespace mace { +namespace { + +class StringUtilTest : public ::testing::Test { +}; + +TEST_F(StringUtilTest, MakeString) { + EXPECT_EQ("Hello 2019", MakeString("Hello", " ", 2019)); +} + +TEST_F(StringUtilTest, ToLower) { + EXPECT_EQ("", ToLower("")); + EXPECT_EQ("hello world!", ToLower("Hello World!")); +} + +TEST_F(StringUtilTest, ToUpper) { + EXPECT_EQ("", ToLower("")); + EXPECT_EQ("HELLO WORLD!", ToUpper("Hello World!")); +} + +} // namespace +} // namespace mace diff --git a/mace/utils/timer.h b/mace/utils/timer.h index 3f0e96f4c37045ecd7c9b9a274a6fbf7dc0a0380..0955af7ba5ce5db65e4493b486e028683f5d1e66 100644 --- a/mace/utils/timer.h +++ b/mace/utils/timer.h @@ -15,7 +15,7 @@ #ifndef MACE_UTILS_TIMER_H_ #define MACE_UTILS_TIMER_H_ -#include "mace/utils/env_time.h" +#include "mace/port/env.h" #include "mace/utils/logging.h" namespace mace { diff --git a/mace/utils/tuner.h b/mace/utils/tuner.h index 7ac8467bce6cf4df2c3c6c4741cf6b630497074d..0a33523ce516553187371949ef944b4217ab2661 100644 --- a/mace/utils/tuner.h +++ b/mace/utils/tuner.h @@ -14,12 +14,14 @@ #ifndef MACE_UTILS_TUNER_H_ #define MACE_UTILS_TUNER_H_ + +// TODO(heliangliang) Fix portability #include -#include #include #include #include +#include #include #include #include @@ -30,8 +32,8 @@ #include #include "mace/utils/logging.h" +#include "mace/utils/string_util.h" #include "mace/utils/timer.h" -#include "mace/utils/utils.h" namespace mace { @@ -293,4 +295,5 @@ class Tuner { }; } // namespace mace + #endif // MACE_UTILS_TUNER_H_ diff --git a/mace/utils/utils.cc b/mace/utils/utils.cc deleted file mode 100644 index 10bbac8267997815378ebb2c63f4142ff6d51819..0000000000000000000000000000000000000000 --- a/mace/utils/utils.cc +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2018 The MACE Authors. 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 "mace/utils/utils.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mace/utils/logging.h" - -namespace mace { - -std::string ObfuscateString(const std::string &src, - const std::string &lookup_table) { - std::string dest; - dest.resize(src.size()); - for (size_t i = 0; i < src.size(); i++) { - dest[i] = src[i] ^ lookup_table[i % lookup_table.size()]; - } - return dest; -} - -// ObfuscateString(ObfuscateString(str)) ==> str -std::string ObfuscateString(const std::string &src) { - // Keep consistent with obfuscation in python tools - return ObfuscateString(src, "Mobile-AI-Compute-Engine"); -} - -// Obfuscate synbol or path string -std::string ObfuscateSymbol(const std::string &src) { - std::string dest = src; - if (dest.empty()) { - return dest; - } - dest[0] = src[0]; // avoid invalid symbol which starts from 0-9 - const std::string encode_dict = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; - for (size_t i = 1; i < src.size(); i++) { - char ch = src[i]; - int idx; - if (ch >= '0' && ch <= '9') { - idx = ch - '0'; - } else if (ch >= 'a' && ch <= 'z') { - idx = 10 + ch - 'a'; - } else if (ch >= 'A' && ch <= 'Z') { - idx = 10 + 26 + ch - 'a'; - } else if (ch == '_') { - idx = 10 + 26 + 26; - } else { - dest[i] = ch; - continue; - } - // There is no collision if it's true for every char at every position - dest[i] = encode_dict[(idx + i + 31) % encode_dict.size()]; - } - return dest; -} - -std::vector Split(const std::string &str, char delims) { - std::vector result; - std::string tmp = str; - while (!tmp.empty()) { - size_t next_offset = tmp.find(delims); - result.push_back(tmp.substr(0, next_offset)); - if (next_offset == std::string::npos) { - break; - } else { - tmp = tmp.substr(next_offset + 1); - } - } - return result; -} - -bool ReadBinaryFile(std::vector *data, - const std::string &filename) { - std::ifstream ifs(filename, std::ios::in | std::ios::binary); - if (!ifs.is_open()) { - return false; - } - ifs.seekg(0, ifs.end); - size_t length = ifs.tellg(); - ifs.seekg(0, ifs.beg); - - data->resize(length); - ifs.read(reinterpret_cast(data->data()), length); - - if (ifs.fail()) { - return false; - } - ifs.close(); - - return true; -} - -void MemoryMap(const std::string &file, - const unsigned char **data, - size_t *size) { - int fd = open(file.c_str(), O_RDONLY); - MACE_CHECK(fd >= 0, - "Failed to open file ", file, ", error code: ", strerror(errno)); - struct stat st; - fstat(fd, &st); - *size = static_cast(st.st_size); - if (*size == 0) { - return; - } - - *data = static_cast( - mmap(nullptr, *size, PROT_READ, MAP_PRIVATE, fd, 0)); - MACE_CHECK(*data != static_cast(MAP_FAILED), - "Failed to map file ", file, ", error code: ", strerror(errno)); - - int ret = close(fd); - MACE_CHECK(ret == 0, - "Failed to close file ", file, ", error code: ", strerror(errno)); -} - -void MemoryUnMap(const unsigned char *data, - const size_t &size) { - if (size == 0) { - return; - } - MACE_CHECK(data != nullptr, "data is null"); - - int ret = munmap(const_cast(data), size); - - MACE_CHECK(ret == 0, - "Failed to unmap file, error code: ", strerror(errno)); -} - -} // namespace mace diff --git a/repository/git/BUILD b/repository/git/BUILD.bazel similarity index 100% rename from repository/git/BUILD rename to repository/git/BUILD.bazel diff --git a/repository/git/BUILD.tpl b/repository/git/BUILD.bazel.tpl similarity index 100% rename from repository/git/BUILD.tpl rename to repository/git/BUILD.bazel.tpl diff --git a/repository/git/git_configure.bzl b/repository/git/git_configure.bzl index ca2b8b2d5d9d158554bb32933a2b9a825081a3bd..aa1ea598970b60b4f3a0b8d79d6e35cf282565e9 100644 --- a/repository/git/git_configure.bzl +++ b/repository/git/git_configure.bzl @@ -2,10 +2,10 @@ """ def _git_version_conf_impl(repository_ctx): repository_ctx.template( - "BUILD", - Label("//repository/git:BUILD.tpl")) + "BUILD.bazel", + Label("//repository/git:BUILD.bazel.tpl")) - mace_root_path = str(repository_ctx.path(Label("@mace//:BUILD")))[:-len("BUILD")] + mace_root_path = str(repository_ctx.path(Label("@mace//:BUILD.bazel")))[:-len("BUILD.bazel")] generated_files_path = repository_ctx.path("gen") diff --git a/repository/opencl-kernel/BUILD b/repository/opencl-kernel/BUILD.bazel similarity index 100% rename from repository/opencl-kernel/BUILD rename to repository/opencl-kernel/BUILD.bazel diff --git a/repository/opencl-kernel/BUILD.tpl b/repository/opencl-kernel/BUILD.bazel.tpl similarity index 100% rename from repository/opencl-kernel/BUILD.tpl rename to repository/opencl-kernel/BUILD.bazel.tpl diff --git a/repository/opencl-kernel/opencl_kernel_configure.bzl b/repository/opencl-kernel/opencl_kernel_configure.bzl index 759233fc77cf1e8a59d07a85dded244ad37ff035..63191cda20032c191992ea3624c13c121c585121 100644 --- a/repository/opencl-kernel/opencl_kernel_configure.bzl +++ b/repository/opencl-kernel/opencl_kernel_configure.bzl @@ -3,11 +3,11 @@ def _opencl_encrypt_kernel_impl(repository_ctx): repository_ctx.template( - "BUILD", - Label("//repository/opencl-kernel:BUILD.tpl"), + "BUILD.bazel", + Label("//repository/opencl-kernel:BUILD.bazel.tpl"), ) - mace_root_path = str(repository_ctx.path(Label("@mace//:BUILD")))[:-len("BUILD")] + mace_root_path = str(repository_ctx.path(Label("@mace//:BUILD.bazel")))[:-len("BUILD.bazel")] generated_files_path = repository_ctx.path("gen") ret = repository_ctx.execute( diff --git a/third_party/caffe/BUILD b/third_party/caffe/BUILD.bazel similarity index 100% rename from third_party/caffe/BUILD rename to third_party/caffe/BUILD.bazel diff --git a/third_party/eigen3/BUILD b/third_party/eigen3/BUILD.bazel similarity index 100% rename from third_party/eigen3/BUILD rename to third_party/eigen3/BUILD.bazel diff --git a/third_party/nnlib/BUILD b/third_party/nnlib/BUILD.bazel similarity index 100% rename from third_party/nnlib/BUILD rename to third_party/nnlib/BUILD.bazel diff --git a/tools/aarch64_compiler/BUILD b/tools/aarch64_compiler/BUILD.bazel similarity index 100% rename from tools/aarch64_compiler/BUILD rename to tools/aarch64_compiler/BUILD.bazel diff --git a/tools/aarch64_compiler/linaro_linux_gcc/BUILD b/tools/aarch64_compiler/linaro_linux_gcc/BUILD.bazel similarity index 100% rename from tools/aarch64_compiler/linaro_linux_gcc/BUILD rename to tools/aarch64_compiler/linaro_linux_gcc/BUILD.bazel diff --git a/tools/arm_compiler/BUILD b/tools/arm_compiler/BUILD.bazel similarity index 100% rename from tools/arm_compiler/BUILD rename to tools/arm_compiler/BUILD.bazel diff --git a/tools/arm_compiler/linaro_linux_gcc/BUILD b/tools/arm_compiler/linaro_linux_gcc/BUILD.bazel similarity index 100% rename from tools/arm_compiler/linaro_linux_gcc/BUILD rename to tools/arm_compiler/linaro_linux_gcc/BUILD.bazel diff --git a/tools/bazel.rc b/tools/bazel.rc index 6ad5d64ac43fc979531d88036626c189218a7b9e..85d7763737feaa50611f4e671f60808aea9e1e07 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -14,6 +14,9 @@ build --copt=-DGEMMLOWP_USE_OPENMP build:symbol_hidden --copt=-fvisibility=hidden # Usage example: bazel build --config android +build:android --linkopt=-pie +build:android --linkopt=-ldl +build:android --linkopt=-llog build:android --distinct_host_configuration=true build:android --crosstool_top=//external:android/crosstool build:android --host_crosstool_top=@bazel_tools//tools/cpp:toolchain diff --git a/tools/bazel_adb_run.py b/tools/bazel_adb_run.py index 37d02b78f993dc4fcb38e9359ba404b4ed89eed5..328620c1f179869e36b4340199a6aefbe85f4466 100644 --- a/tools/bazel_adb_run.py +++ b/tools/bazel_adb_run.py @@ -86,7 +86,7 @@ def parse_args(): type=str, default="all", help="SoCs (ro.board.platform from getprop) to build, " - "comma seperated list or all/random") + "comma seperated list or all/random") parser.add_argument( "--target", type=str, default="//...", help="Bazel target to build") parser.add_argument( @@ -118,8 +118,8 @@ def parse_args(): '--device_yml', type=str, default='', - help='embedded linux device config yml file' - ) + help='embedded linux device config yml file') + parser.add_argument('--vlog_level', type=int, default=0, help='vlog level') return parser.parse_known_args() @@ -130,10 +130,12 @@ def main(unused_args): for target_abi in target_abis: toolchain = infer_toolchain(target_abi) - sh_commands.bazel_build(target, abi=target_abi, - toolchain=toolchain, - enable_neon=FLAGS.enable_neon, - address_sanitizer=FLAGS.address_sanitizer) + sh_commands.bazel_build( + target, + abi=target_abi, + toolchain=toolchain, + enable_neon=FLAGS.enable_neon, + address_sanitizer=FLAGS.address_sanitizer) if FLAGS.run_target: target_devices = DeviceManager.list_devices(FLAGS.device_yml) if FLAGS.target_socs != TargetSOCTag.all and\ @@ -158,12 +160,11 @@ def main(unused_args): bin_name, args=FLAGS.args, opencl_profiling=True, - vlog_level=0, + vlog_level=FLAGS.vlog_level, out_of_range_check=True, address_sanitizer=FLAGS.address_sanitizer, simpleperf=FLAGS.simpleperf) - globals()[FLAGS.stdout_processor](stdouts, dev, - target_abi) + globals()[FLAGS.stdout_processor](stdouts, dev, target_abi) if __name__ == "__main__":