提交 ddcd08ea 编写于 作者: L Liangliang He

Improve portability and add Darwin support

上级 4866947b
......@@ -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 <https://github.com/google/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 <https://github.com/google/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
......@@ -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 = {
......
......@@ -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"
......
......@@ -23,8 +23,7 @@
* --dsp_model_data_file=dsp_model_data.data \
* --run_seconds=10
*/
#include <malloc.h>
#include <stdint.h>
#include <cstdint>
#include <cstdlib>
#include <fstream>
#include <iostream>
......@@ -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"
......
......@@ -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",
......
......@@ -15,14 +15,13 @@
#ifndef MACE_CORE_ALLOCATOR_H_
#define MACE_CORE_ALLOCATOR_H_
#include <stdlib.h>
#include <string.h>
#include <cstdlib>
#include <map>
#include <limits>
#include <vector>
#include <cstring>
#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"
......
......@@ -21,8 +21,9 @@
#include <functional>
#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 {
......
......@@ -20,11 +20,10 @@
#include <vector>
#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<void(CallStats *)> wait_fn = [](CallStats *stats) {
......
......@@ -13,18 +13,18 @@
// limitations under the License.
#include <fcntl.h>
#include <limits.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <climits>
#include <algorithm>
#include <cstring>
#include <memory>
#include <utility>
#include "mace/core/kv_storage.h"
#include "mace/core/macros.h"
#include "mace/utils/macros.h"
#include "mace/utils/logging.h"
namespace mace {
......
......@@ -21,8 +21,9 @@
#include <unordered_set>
#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"
......
......@@ -19,14 +19,16 @@
#include <utility>
#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<Operation> SerialNet::CreateOperation(
}
}
}
std::unique_ptr<Operation> 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<index_t>(op.output_shape(i).dims().begin(),
op.output_shape(i).dims().end()));
tensor_shape_map[op.output(i)] = std::vector<index_t>(
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<index_t>(tensor.dims().begin(),
tensor.dims().end()));
std::vector<index_t>(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<int>(DT_FLOAT));
......
......@@ -18,9 +18,6 @@
#include <omp.h>
#endif
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <algorithm>
#include <cerrno>
#include <cstring>
......@@ -29,8 +26,9 @@
#include <utility>
#include <vector>
#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<float> *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<size_t> &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<MaceStatus> 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<float> 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<CPUFreq> cpu_freq(cpu_max_freqs.size());
......
......@@ -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"
......
......@@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <sys/time.h>
#include <algorithm>
#include <iomanip>
#include <thread> // 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<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
}
}
namespace mace {
#define MACE_MAX_NODE 2048
......
......@@ -24,7 +24,7 @@
#include <vector>
#include <utility>
#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<cl::Platform> 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<cl::Device> 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;
}
......
......@@ -17,6 +17,7 @@
#include <utility>
#include "mace/utils/logging.h"
#include "mace/utils/math.h"
namespace mace {
......
......@@ -20,7 +20,7 @@
#include <vector>
#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 {
......
......@@ -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"],
)
......@@ -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<const std::string, MaceTensor> *output);
private:
const unsigned char *model_data_;
size_t model_data_size_;
std::unique_ptr<port::ReadOnlyMemoryRegion> model_data_;
std::unique_ptr<OpRegistryBase> op_registry_;
DeviceType device_type_;
std::unique_ptr<Device> 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<int>(mace::logging::LogMessage::MinVLogLevel()));
static_cast<int>(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<const unsigned char *>(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)) {
......
# -*- 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):
......
......@@ -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",
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -16,7 +16,7 @@
#include <arm_neon.h>
#endif
#include "mace/core/macros.h"
#include "mace/utils/macros.h"
#include "mace/ops/arm/conv_2d_neon.h"
namespace mace {
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -16,7 +16,7 @@
#include <arm_neon.h>
#endif
#include "mace/core/macros.h"
#include "mace/utils/macros.h"
#include "mace/ops/arm/depthwise_conv2d_neon.h"
namespace mace {
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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
......
......@@ -18,6 +18,8 @@
#include <arm_neon.h>
#include <algorithm>
#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));
......
......@@ -18,7 +18,7 @@
#include <arm_neon.h>
#include <algorithm>
#include "mace/utils/utils.h"
#include "mace/utils/math.h"
#include "mace/utils/quantize.h"
#if !defined(__aarch64__)
......
......@@ -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"
......
......@@ -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"
......
......@@ -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"
......
......@@ -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
......
......@@ -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"
......
......@@ -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 {
......
......@@ -18,7 +18,7 @@
#include <vector>
#include "mace/public/mace.h"
#include "mace/utils/utils.h"
#include "mace/utils/math.h"
namespace mace {
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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;
......
......@@ -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 {
......
......@@ -18,7 +18,7 @@
#include <vector>
#include "mace/public/mace.h"
#include "mace/utils/utils.h"
#include "mace/utils/math.h"
namespace mace {
......
......@@ -18,7 +18,7 @@
#include <vector>
#include "mace/public/mace.h"
#include "mace/utils/utils.h"
#include "mace/utils/math.h"
namespace mace {
......
......@@ -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;
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -19,7 +19,7 @@
#include <vector>
#include "mace/utils/tuner.h"
#include "mace/utils/utils.h"
#include "mace/utils/math.h"
namespace mace {
namespace ops {
......
......@@ -21,13 +21,13 @@
#include <vector>
#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 {
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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;
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -18,7 +18,7 @@
#include <vector>
#include "mace/public/mace.h"
#include "mace/utils/utils.h"
#include "mace/utils/math.h"
namespace mace {
......
......@@ -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;
......
......@@ -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"
......
......@@ -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 {
......
......@@ -85,7 +85,7 @@ class ReduceOp<DeviceType::CPU, T> : public ReduceOpBase {
private:
void Simplify(const Tensor *input) {
std::vector<bool> bitmap(static_cast<uint32_t>(input->dim_size()), false);
if (axis_.size() == 0) {
if (axis_.empty()) {
for (int i = 0; i < input->dim_size(); ++i) {
bitmap[i] = true;
}
......
......@@ -15,6 +15,7 @@
#include <vector>
#include "mace/core/operator.h"
#include "mace/utils/math.h"
namespace mace {
namespace ops {
......
......@@ -134,10 +134,10 @@ class SoftmaxOp<DeviceType::CPU, float> : public Operation {
}
};
#ifdef MACE_ENABLE_QUANTIZE
static const int kInputDeltaIntBits = 6;
static const int kSumExpIntBits = 12;
#ifdef MACE_ENABLE_QUANTIZE
template <>
class SoftmaxOp<DeviceType::CPU, uint8_t> : public Operation {
public:
......
......@@ -32,6 +32,7 @@
#include <memory>
#include "mace/core/operator.h"
#include "mace/utils/math.h"
namespace mace {
namespace ops {
......
......@@ -27,6 +27,7 @@
#include <vector>
#include "mace/core/tensor.h"
#include "gtest/gtest.h"
namespace mace {
namespace ops {
......
......@@ -19,6 +19,7 @@
#include <memory>
#include "mace/core/operator.h"
#include "mace/utils/math.h"
namespace mace {
namespace ops {
......
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",
],
)
# 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.
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,
)
// 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 <errno.h>
#include <unwind.h>
#include <dlfcn.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#ifdef __hexagon__
#include <HAP_perf.h>
#else
#include <sys/time.h>
#endif
#include <cstdint>
#include <memory>
#include <fstream>
#include <string>
#include <vector>
#include <utility>
#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<BacktraceState*>(arg);
uintptr_t pc = _Unwind_GetIP(context);
if (pc) {
if (state->current == state->end) {
return _URC_END_OF_STACK;
} else {
*state->current++ = reinterpret_cast<void*>(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<float> *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<size_t> &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<std::string> AndroidEnv::GetBackTraceUnsafe(int max_steps) {
std::vector<void *> buffer(max_steps, 0);
int steps = BackTrace(buffer.data(), max_steps);
std::vector<std::string> 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<MallocLogger> AndroidEnv::NewMallocLogger(
std::ostringstream *oss,
const std::string &name) {
return make_unique<AndroidMallocLogger>(oss, name);
}
Env *Env::Default() {
static AndroidEnv android_env;
return &android_env;
}
} // namespace port
} // namespace mace
// 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 <memory>
#include <string>
#include <vector>
#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<float> *max_freqs) override;
MaceStatus SchedSetAffinity(const std::vector<size_t> &cpu_ids) override;
FileSystem *GetFileSystem() override;
LogWriter *GetLogWriter() override;
std::vector<std::string> GetBackTraceUnsafe(int max_steps) override;
std::unique_ptr<MallocLogger> 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_
// 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,31 +12,21 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "mace/utils/logging.h"
#include "mace/port/android/logger.h"
#include <stdlib.h>
#include <string.h>
#include <sstream>
#if defined(ANDROID) || defined(__ANDROID__)
#include <android/log.h>
#include <iostream>
#endif
namespace mace {
namespace logging {
LogMessage::LogMessage(const char *fname, int line, int severity)
: fname_(fname), line_(line), severity_(severity) {}
namespace port {
void LogMessage::DealWithFatal() {
// When there is a fatal log, now we simply abort.
abort();
}
void LogMessage::GenerateLogMessage() {
#if defined(ANDROID) || defined(__ANDROID__)
void AndroidLogWriter::WriteLogMessage(const char *fname,
const int line,
const LogLevel severity,
const char *message) {
int android_log_level;
switch (severity_) {
switch (severity) {
case INFO:
android_log_level = ANDROID_LOG_INFO;
break;
......@@ -50,64 +40,19 @@ void LogMessage::GenerateLogMessage() {
android_log_level = ANDROID_LOG_FATAL;
break;
default:
if (severity_ < INFO) {
android_log_level = ANDROID_LOG_VERBOSE;
} else {
android_log_level = ANDROID_LOG_ERROR;
}
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();
}
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());
int LogMessage::MinVLogLevel() {
return MinVLogLevelFromEnv();
// Also log to stderr (for standalone Android apps) and abort.
LogWriter::WriteLogMessage(fname, line, severity, message);
}
} // namespace logging
} // namespace port
} // namespace mace
// 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_
// 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 <malloc.h>
#include <string>
#include <utility>
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
// 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 <malloc.h>
#include <string>
#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_
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,
)
// 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 <execinfo.h>
#include <sys/time.h>
#include <cstddef>
#include <string>
#include <vector>
#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<std::string> 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
// 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 <string>
#include <vector>
#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<std::string> GetBackTraceUnsafe(int max_steps) override;
private:
PosixFileSystem posix_file_system_;
LogWriter log_writer_;
};
} // namespace port
} // namespace mace
#endif // MACE_PORT_DARWIN_ENV_H_
// 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 <sstream>
#include "mace/utils/memory.h"
#include "mace/public/mace.h"
namespace mace {
namespace port {
MaceStatus Env::GetCpuMaxFreq(std::vector<float> *max_freqs) {
return MaceStatus::MACE_UNSUPPORTED;
}
MaceStatus Env::SchedSetAffinity(const std::vector<size_t> &cpu_ids) {
return MaceStatus::MACE_UNSUPPORTED;
}
std::unique_ptr<MallocLogger> Env::NewMallocLogger(
std::ostringstream *oss,
const std::string &name) {
return make_unique<MallocLogger>();
}
} // namespace port
} // namespace mace
// 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 <cstdint>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
#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<float> *max_freqs);
virtual MaceStatus SchedSetAffinity(const std::vector<size_t> &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<std::string> GetBackTraceUnsafe(int max_steps) = 0;
virtual std::unique_ptr<MallocLogger> 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<float> *max_freqs) {
return port::Env::Default()->GetCpuMaxFreq(max_freqs);
}
inline MaceStatus SchedSetAffinity(const std::vector<size_t> &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_
// 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 <gtest/gtest.h>
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<float> freq;
GetCpuMaxFreq(&freq);
std::vector<size_t> cpu_ids;
SchedSetAffinity(cpu_ids);
}
} // namespace
} // namespace mace
// 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 <string>
#include <memory>
#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<ReadOnlyMemoryRegion>* result) = 0;
};
} // namespace port
} // namespace mace
#endif // MACE_PORT_FILE_SYSTEM_H_
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,
)
// 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 <execinfo.h>
#include <sys/time.h>
#include <cstddef>
#include <string>
#include <vector>
#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<std::string> 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
// 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 <string>
#include <vector>
#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<std::string> GetBackTraceUnsafe(int max_steps) override;
private:
PosixFileSystem posix_file_system_;
LogWriter log_writer_;
};
} // namespace port
} // namespace mace
#endif // MACE_PORT_LINUX_ENV_H_
// 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 <cstdlib>
#include <iomanip>
#include <string>
#include <vector>
#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<int>(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<std::string> 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
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册