提交 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 ...@@ -101,17 +101,22 @@ MACE also provides model visualization HTML generated in `builds` directory, gen
Debug engine using log 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``; LOG includes four levels, sorted by severity level: ``INFO``, ``WARNING``, ``ERROR``, ``FATAL``.
Environment variable ``MACE_CPP_MIN_LOG_LEVEL`` can be set to specify log level of users, e.g., The logging severity threshold can be configured via environment variable, e.g. ``MACE_CPP_MIN_LOG_LEVEL=WARNING`` to set as ``WARNING``.
``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. 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. All expensive logging with ``VLOG`` should be guarded with ``if(VLOG_IS_ON(lvl))`` check to avoid normal run overhead.
Logs with higher levels than which is specified will be printed. So simply specifying a very large level number will make all logs printed.
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 .. code:: sh
...@@ -168,9 +173,3 @@ things may be a little bit complicated. ...@@ -168,9 +173,3 @@ things may be a little bit complicated.
# then you can use it as host gdb, e.g., # then you can use it as host gdb, e.g.,
bt bt
...@@ -6,6 +6,22 @@ config_setting( ...@@ -6,6 +6,22 @@ config_setting(
visibility = ["//visibility:public"], 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( config_setting(
name = "android_armv7", name = "android_armv7",
values = { values = {
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include "gflags/gflags.h" #include "gflags/gflags.h"
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/logging.h" #include "mace/utils/logging.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
#include "mace/benchmark/statistics.h" #include "mace/benchmark/statistics.h"
#ifdef MODEL_GRAPH_FORMAT_CODE #ifdef MODEL_GRAPH_FORMAT_CODE
#include "mace/codegen/engine/mace_engine_factory.h" #include "mace/codegen/engine/mace_engine_factory.h"
......
...@@ -23,8 +23,7 @@ ...@@ -23,8 +23,7 @@
* --dsp_model_data_file=dsp_model_data.data \ * --dsp_model_data_file=dsp_model_data.data \
* --run_seconds=10 * --run_seconds=10
*/ */
#include <malloc.h> #include <cstdint>
#include <stdint.h>
#include <cstdlib> #include <cstdlib>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
...@@ -33,7 +32,7 @@ ...@@ -33,7 +32,7 @@
#include "gflags/gflags.h" #include "gflags/gflags.h"
#include "mace/public/mace.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/logging.h"
#include "mace/core/types.h" #include "mace/core/types.h"
......
...@@ -59,14 +59,12 @@ cc_library( ...@@ -59,14 +59,12 @@ cc_library(
]) + if_neon_enabled([ ]) + if_neon_enabled([
"-DMACE_ENABLE_NEON", "-DMACE_ENABLE_NEON",
]), ]),
linkopts = ["-ldl"] + if_android([ linkopts = ["-ldl"],
"-pie",
"-lm",
]),
deps = [ deps = [
"//mace/codegen:generated_version", "//mace/codegen:generated_version",
"//mace/proto:mace_cc", "//mace/proto:mace_cc",
"//mace/utils", "//mace/utils",
"//mace/port",
"@half//:half", "@half//:half",
] + if_opencl_enabled([ ] + if_opencl_enabled([
":opencl_headers", ":opencl_headers",
......
...@@ -15,14 +15,13 @@ ...@@ -15,14 +15,13 @@
#ifndef MACE_CORE_ALLOCATOR_H_ #ifndef MACE_CORE_ALLOCATOR_H_
#define MACE_CORE_ALLOCATOR_H_ #define MACE_CORE_ALLOCATOR_H_
#include <stdlib.h> #include <cstdlib>
#include <string.h>
#include <map> #include <map>
#include <limits> #include <limits>
#include <vector> #include <vector>
#include <cstring> #include <cstring>
#include "mace/core/macros.h" #include "mace/utils/macros.h"
#include "mace/core/types.h" #include "mace/core/types.h"
#include "mace/core/runtime_failure_mock.h" #include "mace/core/runtime_failure_mock.h"
#include "mace/public/mace.h" #include "mace/public/mace.h"
......
...@@ -21,8 +21,9 @@ ...@@ -21,8 +21,9 @@
#include <functional> #include <functional>
#include "mace/core/allocator.h" #include "mace/core/allocator.h"
#include "mace/core/macros.h"
#include "mace/core/types.h" #include "mace/core/types.h"
#include "mace/utils/logging.h"
#include "mace/utils/macros.h"
namespace mace { namespace mace {
namespace core { namespace core {
......
...@@ -20,11 +20,10 @@ ...@@ -20,11 +20,10 @@
#include <vector> #include <vector>
#include "mace/utils/logging.h" #include "mace/utils/logging.h"
#include "mace/public/mace.h"
namespace mace { namespace mace {
struct CallStats;
// Wait the call to finish and get the stats if param is not nullptr // Wait the call to finish and get the stats if param is not nullptr
struct StatsFuture { struct StatsFuture {
std::function<void(CallStats *)> wait_fn = [](CallStats *stats) { std::function<void(CallStats *)> wait_fn = [](CallStats *stats) {
......
...@@ -13,18 +13,18 @@ ...@@ -13,18 +13,18 @@
// limitations under the License. // limitations under the License.
#include <fcntl.h> #include <fcntl.h>
#include <limits.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <climits>
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
#include <memory> #include <memory>
#include <utility> #include <utility>
#include "mace/core/kv_storage.h" #include "mace/core/kv_storage.h"
#include "mace/core/macros.h" #include "mace/utils/macros.h"
#include "mace/utils/logging.h" #include "mace/utils/logging.h"
namespace mace { namespace mace {
......
...@@ -21,8 +21,9 @@ ...@@ -21,8 +21,9 @@
#include <unordered_set> #include <unordered_set>
#include "mace/core/arg_helper.h" #include "mace/core/arg_helper.h"
#include "mace/core/macros.h" #include "mace/utils/macros.h"
#include "mace/utils/logging.h" #include "mace/utils/logging.h"
#include "mace/public/mace.h"
#ifdef MACE_ENABLE_OPENCL #ifdef MACE_ENABLE_OPENCL
#include "mace/core/runtime/opencl/opencl_util.h" #include "mace/core/runtime/opencl/opencl_util.h"
......
...@@ -19,14 +19,16 @@ ...@@ -19,14 +19,16 @@
#include <utility> #include <utility>
#include "mace/core/future.h" #include "mace/core/future.h"
#include "mace/core/macros.h"
#include "mace/core/memory_optimizer.h" #include "mace/core/memory_optimizer.h"
#include "mace/core/net.h" #include "mace/core/net.h"
#include "mace/core/op_context.h" #include "mace/core/op_context.h"
#include "mace/public/mace.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/timer.h"
#include "mace/utils/utils.h"
#ifdef MACE_ENABLE_OPENCL #ifdef MACE_ENABLE_OPENCL
#include "mace/core/runtime/opencl/opencl_util.h" #include "mace/core/runtime/opencl/opencl_util.h"
...@@ -114,9 +116,8 @@ std::unique_ptr<Operation> SerialNet::CreateOperation( ...@@ -114,9 +116,8 @@ std::unique_ptr<Operation> SerialNet::CreateOperation(
} }
} }
} }
std::unique_ptr<Operation> op(
op_registry->CreateOperation(construct_context, device_type)); return op_registry->CreateOperation(construct_context, device_type);
return std::move(op);
} }
SerialNet::SerialNet(const OpRegistryBase *op_registry, SerialNet::SerialNet(const OpRegistryBase *op_registry,
...@@ -148,15 +149,14 @@ SerialNet::SerialNet(const OpRegistryBase *op_registry, ...@@ -148,15 +149,14 @@ SerialNet::SerialNet(const OpRegistryBase *op_registry,
continue; continue;
} }
for (int i = 0; i < op.output_size(); ++i) { for (int i = 0; i < op.output_size(); ++i) {
tensor_shape_map[op.output(i)] = tensor_shape_map[op.output(i)] = std::vector<index_t>(
std::move(std::vector<index_t>(op.output_shape(i).dims().begin(), op.output_shape(i).dims().begin(),
op.output_shape(i).dims().end())); op.output_shape(i).dims().end());
} }
} }
for (auto &tensor : net_def->tensors()) { for (auto &tensor : net_def->tensors()) {
tensor_shape_map[tensor.name()] = tensor_shape_map[tensor.name()] =
std::move(std::vector<index_t>(tensor.dims().begin(), std::vector<index_t>(tensor.dims().begin(), tensor.dims().end());
tensor.dims().end()));
} }
bool has_data_format = false; bool has_data_format = false;
...@@ -468,7 +468,7 @@ MaceStatus SerialNet::Run(RunMetadata *run_metadata) { ...@@ -468,7 +468,7 @@ MaceStatus SerialNet::Run(RunMetadata *run_metadata) {
VLOG(3) << "Operator " << op->debug_def().name() VLOG(3) << "Operator " << op->debug_def().name()
<< " has shape: " << MakeString(op->Output(0)->shape()); << " 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) { for (int i = 0; i < op->OutputSize(); ++i) {
if (op->debug_def().quantize_info_size() == 0) { if (op->debug_def().quantize_info_size() == 0) {
int data_type = op->GetOptionalArg("T", static_cast<int>(DT_FLOAT)); int data_type = op->GetOptionalArg("T", static_cast<int>(DT_FLOAT));
......
...@@ -18,9 +18,6 @@ ...@@ -18,9 +18,6 @@
#include <omp.h> #include <omp.h>
#endif #endif
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <algorithm> #include <algorithm>
#include <cerrno> #include <cerrno>
#include <cstring> #include <cstring>
...@@ -29,8 +26,9 @@ ...@@ -29,8 +26,9 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "mace/core/macros.h" #include "mace/port/env.h"
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/macros.h"
#include "mace/utils/logging.h" #include "mace/utils/logging.h"
namespace mace { namespace mace {
...@@ -44,86 +42,15 @@ struct CPUFreq { ...@@ -44,86 +42,15 @@ struct CPUFreq {
namespace { 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, MaceStatus SetOpenMPThreadsAndAffinityCPUs(int omp_num_threads,
const std::vector<size_t> &cpu_ids) { const std::vector<size_t> &cpu_ids) {
MaceOpenMPThreadCount = omp_num_threads; MaceOpenMPThreadCount = omp_num_threads;
#ifdef MACE_ENABLE_OPENMP #ifdef MACE_ENABLE_OPENMP
if (VLOG_IS_ON(1)) {
VLOG(1) << "Set OpenMP threads number: " << omp_num_threads VLOG(1) << "Set OpenMP threads number: " << omp_num_threads
<< ", CPU core IDs: " << MakeString(cpu_ids); << ", CPU core IDs: " << MakeString(cpu_ids);
}
omp_set_schedule(omp_sched_guided, 1); omp_set_schedule(omp_sched_guided, 1);
omp_set_num_threads(omp_num_threads); omp_set_num_threads(omp_num_threads);
#else #else
...@@ -131,12 +58,6 @@ MaceStatus SetOpenMPThreadsAndAffinityCPUs(int omp_num_threads, ...@@ -131,12 +58,6 @@ MaceStatus SetOpenMPThreadsAndAffinityCPUs(int omp_num_threads,
LOG(WARNING) << "Set OpenMP threads number failed: OpenMP not enabled."; LOG(WARNING) << "Set OpenMP threads number failed: OpenMP not enabled.";
#endif #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 #ifdef MACE_ENABLE_OPENMP
std::vector<MaceStatus> status(omp_num_threads, std::vector<MaceStatus> status(omp_num_threads,
MaceStatus::MACE_INVALID_ARGS); MaceStatus::MACE_INVALID_ARGS);
...@@ -144,7 +65,7 @@ MaceStatus SetOpenMPThreadsAndAffinityCPUs(int omp_num_threads, ...@@ -144,7 +65,7 @@ MaceStatus SetOpenMPThreadsAndAffinityCPUs(int omp_num_threads,
for (int i = 0; i < omp_num_threads; ++i) { for (int i = 0; i < omp_num_threads; ++i) {
VLOG(1) << "Set affinity for OpenMP thread " << omp_get_thread_num() VLOG(1) << "Set affinity for OpenMP thread " << omp_get_thread_num()
<< "/" << omp_get_num_threads(); << "/" << omp_get_num_threads();
status[i] = SetThreadAffinity(mask); status[i] = SchedSetAffinity(cpu_ids);
} }
for (int i = 0; i < omp_num_threads; ++i) { for (int i = 0; i < omp_num_threads; ++i) {
if (status[i] != MaceStatus::MACE_SUCCESS) if (status[i] != MaceStatus::MACE_SUCCESS)
...@@ -152,8 +73,10 @@ MaceStatus SetOpenMPThreadsAndAffinityCPUs(int omp_num_threads, ...@@ -152,8 +73,10 @@ MaceStatus SetOpenMPThreadsAndAffinityCPUs(int omp_num_threads,
} }
return MaceStatus::MACE_SUCCESS; return MaceStatus::MACE_SUCCESS;
#else #else
MaceStatus status = SetThreadAffinity(mask); MaceStatus status = SchedSetAffinity(cpu_ids);
VLOG(1) << "Set affinity without OpenMP: " << mask.__bits[0]; if (VLOG_IS_ON(1)) {
VLOG(1) << "Set affinity without OpenMP: " << MakeString(cpu_ids);
}
return status; return status;
#endif #endif
} }
...@@ -166,8 +89,9 @@ MaceStatus CPURuntime::SetOpenMPThreadsAndAffinityPolicy( ...@@ -166,8 +89,9 @@ MaceStatus CPURuntime::SetOpenMPThreadsAndAffinityPolicy(
void *gemm_context) { void *gemm_context) {
// get cpu frequency info // get cpu frequency info
std::vector<float> cpu_max_freqs; std::vector<float> cpu_max_freqs;
if (GetCPUMaxFreq(&cpu_max_freqs) == -1 || cpu_max_freqs.size() == 0) { MACE_RETURN_IF_ERROR(GetCpuMaxFreq(&cpu_max_freqs));
return MaceStatus::MACE_INVALID_ARGS; if (cpu_max_freqs.empty()) {
return MaceStatus::MACE_RUNTIME_ERROR;
} }
std::vector<CPUFreq> cpu_freq(cpu_max_freqs.size()); std::vector<CPUFreq> cpu_freq(cpu_max_freqs.size());
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "public/gemmlowp.h" #include "public/gemmlowp.h"
#endif // MACE_ENABLE_QUANTIZE #endif // MACE_ENABLE_QUANTIZE
#include "mace/core/macros.h" #include "mace/utils/macros.h"
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/logging.h" #include "mace/utils/logging.h"
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include <sys/time.h>
#include <algorithm> #include <algorithm>
#include <iomanip> #include <iomanip>
#include <thread> // NOLINT(build/c++11) #include <thread> // NOLINT(build/c++11)
...@@ -24,16 +23,9 @@ ...@@ -24,16 +23,9 @@
#include "mace/core/runtime/hexagon/hexagon_control_wrapper.h" #include "mace/core/runtime/hexagon/hexagon_control_wrapper.h"
#include "mace/core/runtime/hexagon/hexagon_nn_ops.h" #include "mace/core/runtime/hexagon/hexagon_nn_ops.h"
#include "mace/core/types.h" #include "mace/core/types.h"
#include "mace/port/env.h"
#include "mace/utils/quantize.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 { namespace mace {
#define MACE_MAX_NODE 2048 #define MACE_MAX_NODE 2048
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <vector> #include <vector>
#include <utility> #include <utility>
#include "mace/core/macros.h" #include "mace/utils/macros.h"
#include "mace/core/kv_storage.h" #include "mace/core/kv_storage.h"
#include "mace/core/runtime/opencl/opencl_extension.h" #include "mace/core/runtime/opencl/opencl_extension.h"
#include "mace/utils/tuner.h" #include "mace/utils/tuner.h"
...@@ -273,7 +273,7 @@ OpenCLRuntime::OpenCLRuntime( ...@@ -273,7 +273,7 @@ OpenCLRuntime::OpenCLRuntime(
gpu_type_(UNKNOWN) { gpu_type_(UNKNOWN) {
std::vector<cl::Platform> all_platforms; std::vector<cl::Platform> all_platforms;
cl::Platform::get(&all_platforms); cl::Platform::get(&all_platforms);
if (all_platforms.size() == 0) { if (all_platforms.empty()) {
LOG(ERROR) << "No OpenCL platforms found"; LOG(ERROR) << "No OpenCL platforms found";
return; return;
} }
...@@ -289,7 +289,7 @@ OpenCLRuntime::OpenCLRuntime( ...@@ -289,7 +289,7 @@ OpenCLRuntime::OpenCLRuntime(
// get default device (CPUs, GPUs) of the default platform // get default device (CPUs, GPUs) of the default platform
std::vector<cl::Device> all_devices; std::vector<cl::Device> all_devices;
default_platform.getDevices(CL_DEVICE_TYPE_ALL, &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"; LOG(ERROR) << "No OpenCL devices found";
return; return;
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <utility> #include <utility>
#include "mace/utils/logging.h" #include "mace/utils/logging.h"
#include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <vector> #include <vector>
#include "mace/core/testing/test_benchmark.h" #include "mace/core/testing/test_benchmark.h"
#include "mace/utils/env_time.h" #include "mace/port/env.h"
#include "mace/utils/logging.h" #include "mace/utils/logging.h"
namespace mace { namespace mace {
......
...@@ -10,13 +10,13 @@ licenses(["notice"]) # Apache 2.0 ...@@ -10,13 +10,13 @@ licenses(["notice"]) # Apache 2.0
load( load(
"//mace:mace.bzl", "//mace:mace.bzl",
"if_android", "if_android",
"if_linux",
"if_darwin",
"if_neon_enabled", "if_neon_enabled",
"if_neon_enabled_str",
"if_openmp_enabled", "if_openmp_enabled",
"if_android_armv7", "if_android_armv7",
"if_hexagon_enabled", "if_hexagon_enabled",
"if_opencl_enabled", "if_opencl_enabled",
"if_opencl_enabled_str",
"if_quantize_enabled", "if_quantize_enabled",
) )
...@@ -77,6 +77,7 @@ cc_library( ...@@ -77,6 +77,7 @@ cc_library(
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
# For details, see https://github.com/bazelbuild/bazel/issues/5200
genrule( genrule(
name = "libmace_static", name = "libmace_static",
srcs = [ srcs = [
...@@ -87,10 +88,18 @@ genrule( ...@@ -87,10 +88,18 @@ genrule(
"//mace/ops:internal_ops", "//mace/ops:internal_ops",
"//mace/ops", "//mace/ops",
"//mace/libmace", "//mace/libmace",
"//mace/port:port_base",
"//mace/port/posix:port_posix",
"//mace/utils", "//mace/utils",
"//mace/proto:mace_cc", "//mace/proto:mace_cc",
"@com_google_protobuf//:protobuf_lite", "@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/ops:opencl_kernels",
"//mace/codegen:generated_opencl", "//mace/codegen:generated_opencl",
]) + if_neon_enabled([ ]) + if_neon_enabled([
...@@ -103,20 +112,43 @@ genrule( ...@@ -103,20 +112,43 @@ genrule(
"$(locations //mace/core:core) " + "$(locations //mace/core:core) " +
"$(locations //mace/ops:common) " + "$(locations //mace/ops:common) " +
"$(locations //mace/ops:ref_kernels) " + "$(locations //mace/ops:ref_kernels) " +
if_neon_enabled_str("$(locations //mace/ops:arm_neon_kernels) ") + if_neon_enabled(
if_opencl_enabled_str("$(locations //mace/ops:opencl_kernels) ") + "$(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:internal_ops) " +
"$(locations //mace/ops:ops) " + "$(locations //mace/ops:ops) " +
"$(locations //mace/libmace:libmace) " + "$(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/utils:utils) " +
"$(locations //mace/proto:mace_cc) " + "$(locations //mace/proto:mace_cc) " +
"$(locations @com_google_protobuf//:protobuf_lite) " + "$(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);" + "$$tmp_mri_file);" +
"$(AR) -M <$$tmp_mri_file;" + "$(AR) -M <$$tmp_mri_file;" +
"rm -rf $$tmp_mri_file;" + "rm -rf $$tmp_mri_file;",
"$(STRIP) -x $@;", # "$(STRIP) -x $@;", # FIXME this will crash
tools = ["//mace/python/tools:archive_static_lib"], tools = ["//mace/python/tools:archive_static_lib"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
...@@ -21,7 +21,12 @@ ...@@ -21,7 +21,12 @@
#include "mace/core/net.h" #include "mace/core/net.h"
#include "mace/ops/ops_registry.h" #include "mace/ops/ops_registry.h"
#include "mace/ops/common/transpose.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/public/mace.h"
#include "mace/port/env.h"
#include "mace/port/file_system.h"
#ifdef MACE_ENABLE_OPENCL #ifdef MACE_ENABLE_OPENCL
#include "mace/core/runtime/opencl/gpu_device.h" #include "mace/core/runtime/opencl/gpu_device.h"
...@@ -33,8 +38,6 @@ ...@@ -33,8 +38,6 @@
#include "mace/core/runtime/hexagon/hexagon_device.h" #include "mace/core/runtime/hexagon/hexagon_device.h"
#endif // MACE_ENABLE_HEXAGON #endif // MACE_ENABLE_HEXAGON
#include "mace/utils/memory.h"
namespace mace { namespace mace {
namespace { namespace {
...@@ -377,8 +380,7 @@ class MaceEngine::Impl { ...@@ -377,8 +380,7 @@ class MaceEngine::Impl {
std::pair<const std::string, MaceTensor> *output); std::pair<const std::string, MaceTensor> *output);
private: private:
const unsigned char *model_data_; std::unique_ptr<port::ReadOnlyMemoryRegion> model_data_;
size_t model_data_size_;
std::unique_ptr<OpRegistryBase> op_registry_; std::unique_ptr<OpRegistryBase> op_registry_;
DeviceType device_type_; DeviceType device_type_;
std::unique_ptr<Device> device_; std::unique_ptr<Device> device_;
...@@ -396,7 +398,6 @@ class MaceEngine::Impl { ...@@ -396,7 +398,6 @@ class MaceEngine::Impl {
MaceEngine::Impl::Impl(const MaceEngineConfig &config) MaceEngine::Impl::Impl(const MaceEngineConfig &config)
: model_data_(nullptr), : model_data_(nullptr),
model_data_size_(0),
op_registry_(new OpRegistry), op_registry_(new OpRegistry),
device_type_(config.impl_->device_type()), device_type_(config.impl_->device_type()),
device_(nullptr), device_(nullptr),
...@@ -490,7 +491,7 @@ MaceStatus MaceEngine::Impl::Init( ...@@ -490,7 +491,7 @@ MaceStatus MaceEngine::Impl::Init(
MACE_CHECK(hexagon_controller_->Config(), "hexagon config error"); MACE_CHECK(hexagon_controller_->Config(), "hexagon config error");
MACE_CHECK(hexagon_controller_->Init(), "hexagon init error"); MACE_CHECK(hexagon_controller_->Init(), "hexagon init error");
hexagon_controller_->SetDebugLevel( 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), MACE_CHECK(hexagon_controller_->SetupGraph(*net_def, model_data),
"hexagon setup graph error"); "hexagon setup graph error");
if (VLOG_IS_ON(2)) { if (VLOG_IS_ON(2)) {
...@@ -532,23 +533,22 @@ MaceStatus MaceEngine::Impl::Init( ...@@ -532,23 +533,22 @@ MaceStatus MaceEngine::Impl::Init(
const std::string &model_data_file) { const std::string &model_data_file) {
LOG(INFO) << "Loading Model Data"; 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 || if (device_type_ == DeviceType::GPU || device_type_ == DeviceType::HEXAGON ||
(device_type_ == DeviceType::CPU && ws_->diffused_buffer())) { (device_type_ == DeviceType::CPU && ws_->diffused_buffer())) {
MemoryUnMap(model_data_, model_data_size_); model_data_.reset();
model_data_ = nullptr;
} }
return MaceStatus::MACE_SUCCESS; return MaceStatus::MACE_SUCCESS;
} }
MaceEngine::Impl::~Impl() { MaceEngine::Impl::~Impl() {
LOG(INFO) << "Destroying MaceEngine"; LOG(INFO) << "Destroying MaceEngine";
if (model_data_ != nullptr) {
MemoryUnMap(model_data_, model_data_size_);
}
#ifdef MACE_ENABLE_HEXAGON #ifdef MACE_ENABLE_HEXAGON
if (device_type_ == HEXAGON) { if (device_type_ == HEXAGON) {
if (VLOG_IS_ON(2)) { if (VLOG_IS_ON(2)) {
......
# -*- Python -*- # -*- Python -*-
def if_android(a): def if_android(a, default_value = []):
return select({ return select({
"//mace:android": a, "//mace:android": a,
"//conditions:default": [], "//conditions:default": default_value,
}) })
def if_not_android(a): def if_linux(a, default_value = []):
return select({ return select({
"//mace:android": [], "//mace:linux": a,
"//conditions:default": 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): def if_android_armv7(a):
...@@ -36,16 +42,10 @@ def if_arm_linux_armhf(a): ...@@ -36,16 +42,10 @@ def if_arm_linux_armhf(a):
"//conditions:default": [] "//conditions:default": []
}) })
def if_neon_enabled(a): def if_neon_enabled(a, default_value = []):
return select({ return select({
"//mace:neon_enabled": a, "//mace:neon_enabled": a,
"//conditions:default": [], "//conditions:default": default_value,
})
def if_neon_enabled_str(a):
return select({
"//mace:neon_enabled": a,
"//conditions:default": "",
}) })
def if_hexagon_enabled(a): def if_hexagon_enabled(a):
...@@ -66,16 +66,10 @@ def if_openmp_enabled(a): ...@@ -66,16 +66,10 @@ def if_openmp_enabled(a):
"//conditions:default": [], "//conditions:default": [],
}) })
def if_opencl_enabled(a): def if_opencl_enabled(a, default_value = []):
return select({
"//mace:opencl_enabled": a,
"//conditions:default": [],
})
def if_opencl_enabled_str(a):
return select({ return select({
"//mace:opencl_enabled": a, "//mace:opencl_enabled": a,
"//conditions:default": "", "//conditions:default": default_value,
}) })
def if_quantize_enabled(a): def if_quantize_enabled(a):
......
...@@ -54,34 +54,14 @@ cc_library( ...@@ -54,34 +54,14 @@ cc_library(
cc_library( cc_library(
name = "testing", name = "testing",
srcs = glob( hdrs = [
[ "testing/test_utils.h",
"testing/*.cc",
],
),
hdrs = glob(
[
"testing/*.h",
], ],
),
copts = [ copts = [
"-Werror", "-Werror",
"-Wextra", "-Wextra",
"-Wno-missing-field-initializers", "-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 = [ deps = [
"//mace/core", "//mace/core",
"@gtest", "@gtest",
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#endif #endif
#include "mace/ops/arm/conv_2d_neon.h" #include "mace/ops/arm/conv_2d_neon.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
namespace ops { namespace ops {
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include "mace/ops/arm/conv_2d_neon.h" #include "mace/ops/arm/conv_2d_neon.h"
#include "mace/utils/logging.h" #include "mace/utils/logging.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
namespace ops { namespace ops {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <arm_neon.h> #include <arm_neon.h>
#endif #endif
#include "mace/core/macros.h" #include "mace/utils/macros.h"
#include "mace/ops/arm/conv_2d_neon.h" #include "mace/ops/arm/conv_2d_neon.h"
namespace mace { namespace mace {
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "mace/core/macros.h" #include "mace/utils/macros.h"
#include "mace/ops/arm/deconv_2d_neon.h" #include "mace/ops/arm/deconv_2d_neon.h"
namespace mace { namespace mace {
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "mace/core/macros.h" #include "mace/utils/macros.h"
#include "mace/ops/arm/deconv_2d_neon.h" #include "mace/ops/arm/deconv_2d_neon.h"
namespace mace { namespace mace {
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "mace/core/macros.h" #include "mace/utils/macros.h"
#include "mace/ops/arm/deconv_2d_neon.h" #include "mace/ops/arm/deconv_2d_neon.h"
namespace mace { namespace mace {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <arm_neon.h> #include <arm_neon.h>
#endif #endif
#include "mace/core/macros.h" #include "mace/utils/macros.h"
#include "mace/ops/arm/depthwise_conv2d_neon.h" #include "mace/ops/arm/depthwise_conv2d_neon.h"
namespace mace { namespace mace {
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "mace/core/macros.h" #include "mace/utils/macros.h"
#include "mace/ops/arm/depthwise_deconv2d_neon.h" #include "mace/ops/arm/depthwise_deconv2d_neon.h"
namespace mace { namespace mace {
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "mace/core/macros.h" #include "mace/utils/macros.h"
#include "mace/ops/arm/deconv_2d_neon.h" #include "mace/ops/arm/deconv_2d_neon.h"
namespace mace { namespace mace {
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include "mace/ops/arm/fp32/conv_2d_3x3_winograd.h" #include "mace/ops/arm/fp32/conv_2d_3x3_winograd.h"
#include "mace/ops/common/conv_pool_2d_util.h" #include "mace/ops/common/conv_pool_2d_util.h"
#include "mace/utils/memory.h"
#include "mace/utils/math.h"
namespace mace { namespace mace {
namespace ops { namespace ops {
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "mace/core/tensor.h" #include "mace/core/tensor.h"
#include "mace/core/op_context.h" #include "mace/core/op_context.h"
#include "mace/ops/common/matrix.h" #include "mace/ops/common/matrix.h"
#include "mace/utils/math.h"
// This implements matrix-matrix multiplication. // This implements matrix-matrix multiplication.
// In the case of matrix-vector multiplication, use gemv.h/gemv.cc instead // In the case of matrix-vector multiplication, use gemv.h/gemv.cc instead
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#include <arm_neon.h> #include <arm_neon.h>
#include <algorithm> #include <algorithm>
#include "mace/utils/math.h"
#if !defined(__aarch64__) #if !defined(__aarch64__)
float vaddvq_f32(float32x4_t v) { float vaddvq_f32(float32x4_t v) {
float32x2_t _sum = vadd_f32(vget_low_f32(v), vget_high_f32(v)); float32x2_t _sum = vadd_f32(vget_low_f32(v), vget_high_f32(v));
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <arm_neon.h> #include <arm_neon.h>
#include <algorithm> #include <algorithm>
#include "mace/utils/utils.h" #include "mace/utils/math.h"
#include "mace/utils/quantize.h" #include "mace/utils/quantize.h"
#if !defined(__aarch64__) #if !defined(__aarch64__)
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "mace/core/runtime/opencl/opencl_runtime.h"
#include "mace/core/testing/test_benchmark.h" #include "mace/core/testing/test_benchmark.h"
#include "mace/ops/ops_test_util.h" #include "mace/ops/ops_test_util.h"
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include "mace/ops/conv_pool_2d_base.h" #include "mace/ops/conv_pool_2d_base.h"
#include "mace/ops/common/conv_pool_2d_util.h" #include "mace/ops/common/conv_pool_2d_util.h"
#include "mace/utils/memory.h" #include "mace/utils/memory.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
#ifdef MACE_ENABLE_NEON #ifdef MACE_ENABLE_NEON
#include "mace/ops/arm/fp32/conv_2d.h" #include "mace/ops/arm/fp32/conv_2d.h"
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "mace/ops/activation.h" #include "mace/ops/activation.h"
#include "mace/ops/arm/deconv_2d_neon.h" #include "mace/ops/arm/deconv_2d_neon.h"
#include "mace/utils/memory.h" #include "mace/utils/memory.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
#ifdef MACE_ENABLE_OPENCL #ifdef MACE_ENABLE_OPENCL
#include "mace/ops/opencl/buffer_transformer.h" #include "mace/ops/opencl/buffer_transformer.h"
#include "mace/ops/opencl/image/deconv_2d.h" #include "mace/ops/opencl/image/deconv_2d.h"
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include "mace/core/future.h" #include "mace/core/future.h"
#include "mace/core/tensor.h" #include "mace/core/tensor.h"
#include "mace/ops/arm/depthwise_deconv2d_neon.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/public/mace.h"
#include "mace/utils/memory.h" #include "mace/utils/memory.h"
#ifdef MACE_ENABLE_OPENCL #ifdef MACE_ENABLE_OPENCL
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include "mace/core/operator.h" #include "mace/core/operator.h"
#include "mace/core/tensor.h" #include "mace/core/tensor.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
#ifdef MACE_ENABLE_NEON #ifdef MACE_ENABLE_NEON
#include "mace/ops/arm/fp32/gemm.h" #include "mace/ops/arm/fp32/gemm.h"
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define MACE_OPS_OPENCL_ACTIVATION_H_ #define MACE_OPS_OPENCL_ACTIVATION_H_
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <vector> #include <vector>
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define MACE_OPS_OPENCL_BATCH_NORM_H_ #define MACE_OPS_OPENCL_BATCH_NORM_H_
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "mace/core/types.h" #include "mace/core/types.h"
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define MACE_OPS_OPENCL_BIAS_ADD_H_ #define MACE_OPS_OPENCL_BIAS_ADD_H_
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include "mace/core/runtime/opencl/opencl_util.h" #include "mace/core/runtime/opencl/opencl_util.h"
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
class OpContext; class OpContext;
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define MACE_OPS_OPENCL_CHANNEL_SHUFFLE_H_ #define MACE_OPS_OPENCL_CHANNEL_SHUFFLE_H_
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <vector> #include <vector>
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <vector> #include <vector>
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define MACE_OPS_OPENCL_DEPTH_TO_SPACE_H_ #define MACE_OPS_OPENCL_DEPTH_TO_SPACE_H_
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
class OpContext; class OpContext;
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define MACE_OPS_OPENCL_ELTWISE_H_ #define MACE_OPS_OPENCL_ELTWISE_H_
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include "mace/ops/activation.h" #include "mace/ops/activation.h"
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <vector> #include <vector>
#include "mace/utils/tuner.h" #include "mace/utils/tuner.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
namespace ops { namespace ops {
......
...@@ -21,13 +21,13 @@ ...@@ -21,13 +21,13 @@
#include <vector> #include <vector>
#include "mace/core/future.h" #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/cl2_header.h"
#include "mace/core/runtime/opencl/opencl_runtime.h" #include "mace/core/runtime/opencl/opencl_runtime.h"
#include "mace/core/runtime/opencl/opencl_util.h" #include "mace/core/runtime/opencl/opencl_util.h"
#include "mace/core/types.h" #include "mace/core/types.h"
#include "mace/utils/memory.h" #include "mace/utils/memory.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
namespace ops { namespace ops {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include "mace/core/runtime/opencl/opencl_runtime.h" #include "mace/core/runtime/opencl/opencl_runtime.h"
#include "mace/ops/common/activation_type.h" #include "mace/ops/common/activation_type.h"
#include "mace/ops/opencl/helper.h" #include "mace/ops/opencl/helper.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
namespace ops { namespace ops {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include "mace/core/runtime/opencl/opencl_runtime.h" #include "mace/core/runtime/opencl/opencl_runtime.h"
#include "mace/ops/opencl/helper.h" #include "mace/ops/opencl/helper.h"
#include "mace/ops/common/activation_type.h" #include "mace/ops/common/activation_type.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
namespace ops { namespace ops {
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include "mace/ops/common/conv_pool_2d_util.h" #include "mace/ops/common/conv_pool_2d_util.h"
#include "mace/ops/opencl/helper.h" #include "mace/ops/opencl/helper.h"
#include "mace/utils/memory.h" #include "mace/utils/memory.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
namespace ops { namespace ops {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define MACE_OPS_OPENCL_LSTM_CELL_H_ #define MACE_OPS_OPENCL_LSTM_CELL_H_
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define MACE_OPS_OPENCL_MATMUL_H_ #define MACE_OPS_OPENCL_MATMUL_H_
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define MACE_OPS_OPENCL_PAD_H_ #define MACE_OPS_OPENCL_PAD_H_
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
class OpContext; class OpContext;
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define MACE_OPS_OPENCL_REDUCE_H_ #define MACE_OPS_OPENCL_REDUCE_H_
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define MACE_OPS_OPENCL_RESIZE_BICUBIC_H_ #define MACE_OPS_OPENCL_RESIZE_BICUBIC_H_
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
#include "mace/core/types.h" #include "mace/core/types.h"
namespace mace { namespace mace {
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include "mace/core/types.h" #include "mace/core/types.h"
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include "mace/core/types.h" #include "mace/core/types.h"
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define MACE_OPS_OPENCL_SOFTMAX_H_ #define MACE_OPS_OPENCL_SOFTMAX_H_
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "mace/core/types.h" #include "mace/core/types.h"
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define MACE_OPS_OPENCL_SPACE_TO_DEPTH_H_ #define MACE_OPS_OPENCL_SPACE_TO_DEPTH_H_
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <vector> #include <vector>
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define MACE_OPS_OPENCL_SQRDIFF_MEAN_H_ #define MACE_OPS_OPENCL_SQRDIFF_MEAN_H_
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
namespace mace { namespace mace {
class OpContext; class OpContext;
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#include "mace/ops/ops_registry.h" #include "mace/ops/ops_registry.h"
#include "mace/public/mace.h" #include "mace/public/mace.h"
#include "mace/utils/memory.h" #include "mace/utils/memory.h"
#include "mace/utils/utils.h" #include "mace/utils/math.h"
#include "mace/utils/quantize.h" #include "mace/utils/quantize.h"
#include "mace/ops/testing/test_utils.h" #include "mace/ops/testing/test_utils.h"
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "mace/ops/opencl/image/pad.h" #include "mace/ops/opencl/image/pad.h"
#endif // MACE_ENABLE_OPENCL #endif // MACE_ENABLE_OPENCL
#include "mace/utils/memory.h" #include "mace/utils/memory.h"
#include "mace/utils/math.h"
namespace mace { namespace mace {
namespace ops { namespace ops {
......
...@@ -85,7 +85,7 @@ class ReduceOp<DeviceType::CPU, T> : public ReduceOpBase { ...@@ -85,7 +85,7 @@ class ReduceOp<DeviceType::CPU, T> : public ReduceOpBase {
private: private:
void Simplify(const Tensor *input) { void Simplify(const Tensor *input) {
std::vector<bool> bitmap(static_cast<uint32_t>(input->dim_size()), false); 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) { for (int i = 0; i < input->dim_size(); ++i) {
bitmap[i] = true; bitmap[i] = true;
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <vector> #include <vector>
#include "mace/core/operator.h" #include "mace/core/operator.h"
#include "mace/utils/math.h"
namespace mace { namespace mace {
namespace ops { namespace ops {
......
...@@ -134,10 +134,10 @@ class SoftmaxOp<DeviceType::CPU, float> : public Operation { ...@@ -134,10 +134,10 @@ class SoftmaxOp<DeviceType::CPU, float> : public Operation {
} }
}; };
#ifdef MACE_ENABLE_QUANTIZE
static const int kInputDeltaIntBits = 6; static const int kInputDeltaIntBits = 6;
static const int kSumExpIntBits = 12; static const int kSumExpIntBits = 12;
#ifdef MACE_ENABLE_QUANTIZE
template <> template <>
class SoftmaxOp<DeviceType::CPU, uint8_t> : public Operation { class SoftmaxOp<DeviceType::CPU, uint8_t> : public Operation {
public: public:
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <memory> #include <memory>
#include "mace/core/operator.h" #include "mace/core/operator.h"
#include "mace/utils/math.h"
namespace mace { namespace mace {
namespace ops { namespace ops {
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <vector> #include <vector>
#include "mace/core/tensor.h" #include "mace/core/tensor.h"
#include "gtest/gtest.h"
namespace mace { namespace mace {
namespace ops { namespace ops {
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <memory> #include <memory>
#include "mace/core/operator.h" #include "mace/core/operator.h"
#include "mace/utils/math.h"
namespace mace { namespace mace {
namespace ops { 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"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
...@@ -12,31 +12,21 @@ ...@@ -12,31 +12,21 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // 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 <android/log.h>
#include <iostream> #include <iostream>
#endif
namespace mace { namespace mace {
namespace logging { namespace port {
LogMessage::LogMessage(const char *fname, int line, int severity)
: fname_(fname), line_(line), severity_(severity) {}
void LogMessage::DealWithFatal() { void AndroidLogWriter::WriteLogMessage(const char *fname,
// When there is a fatal log, now we simply abort. const int line,
abort(); const LogLevel severity,
} const char *message) {
void LogMessage::GenerateLogMessage() {
#if defined(ANDROID) || defined(__ANDROID__)
int android_log_level; int android_log_level;
switch (severity_) { switch (severity) {
case INFO: case INFO:
android_log_level = ANDROID_LOG_INFO; android_log_level = ANDROID_LOG_INFO;
break; break;
...@@ -50,64 +40,19 @@ void LogMessage::GenerateLogMessage() { ...@@ -50,64 +40,19 @@ void LogMessage::GenerateLogMessage() {
android_log_level = ANDROID_LOG_FATAL; android_log_level = ANDROID_LOG_FATAL;
break; break;
default: default:
if (severity_ < INFO) {
android_log_level = ANDROID_LOG_VERBOSE;
} else {
android_log_level = ANDROID_LOG_ERROR; android_log_level = ANDROID_LOG_ERROR;
}
break; break;
} }
std::stringstream ss; std::stringstream ss;
const char *const partial_name = strrchr(fname_, '/'); const char *const partial_name = strrchr(fname, '/');
ss << (partial_name != nullptr ? partial_name + 1 : fname_) << ":" << line_ ss << (partial_name != nullptr ? partial_name + 1 : fname) << ":" << line
<< " " << str(); << " " << message;
__android_log_write(android_log_level, "MACE", ss.str().c_str()); __android_log_write(android_log_level, "CRT", 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() { // Also log to stderr (for standalone Android apps) and abort.
return MinVLogLevelFromEnv(); LogWriter::WriteLogMessage(fname, line, severity, message);
} }
} // namespace logging } // namespace port
} // namespace mace } // 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
// 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 <cstdlib>
#include <cstring>
#include <sstream>
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_
// 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 <gtest/gtest.h>
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
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",
],
)
// 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 <execinfo.h>
#include <string>
#include <vector>
namespace mace {
namespace port {
namespace posix {
inline std::vector<std::string> GetBackTraceUnsafe(int max_steps) {
std::vector<void *> buffer(max_steps, 0);
int steps = backtrace(buffer.data(), max_steps);
std::vector<std::string> 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_
// 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 <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <memory>
#include <string>
#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<void *>(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<ReadOnlyMemoryRegion>* 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<PosixReadOnlyMemoryRegion>(address, st.st_size);
}
close(fd);
}
return s;
}
} // 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_POSIX_FILE_SYSTEM_H_
#define MACE_PORT_POSIX_FILE_SYSTEM_H_
#include <string>
#include <memory>
#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<ReadOnlyMemoryRegion>* result) override;
};
} // namespace port
} // namespace mace
#endif // MACE_PORT_POSIX_FILE_SYSTEM_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"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
...@@ -12,28 +12,25 @@ ...@@ -12,28 +12,25 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef MACE_UTILS_ENV_TIME_H_ #ifndef MACE_PORT_POSIX_TIME_H_
#define MACE_UTILS_ENV_TIME_H_ #define MACE_PORT_POSIX_TIME_H_
#include <stdint.h>
#ifdef __hexagon__
#include <HAP_perf.h>
#else
#include <sys/time.h> #include <sys/time.h>
#endif
#include <cstddef>
namespace mace { namespace mace {
namespace port {
namespace posix {
inline int64_t NowMicros() { inline int64_t NowMicros() {
#ifdef __hexagon__
return HAP_perf_get_time_us();
#else
struct timeval tv; struct timeval tv;
gettimeofday(&tv, nullptr); gettimeofday(&tv, nullptr);
return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec; return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
#endif
} }
} // namespace posix
} // namespace port
} // namespace mace } // namespace mace
#endif // MACE_UTILS_ENV_TIME_H_ #endif // MACE_PORT_POSIX_TIME_H_
...@@ -12,5 +12,8 @@ cc_library( ...@@ -12,5 +12,8 @@ cc_library(
hdrs = [ hdrs = [
"mace.h", "mace.h",
], ],
srcs = [
"status.cc",
],
copts = ["-Werror", "-Wextra", "-Wno-missing-field-initializers"], copts = ["-Werror", "-Wextra", "-Wno-missing-field-initializers"],
) )
...@@ -144,7 +144,9 @@ class MaceStatus { ...@@ -144,7 +144,9 @@ class MaceStatus {
enum Code { enum Code {
MACE_SUCCESS = 0, MACE_SUCCESS = 0,
MACE_INVALID_ARGS = 1, MACE_INVALID_ARGS = 1,
MACE_OUT_OF_RESOURCES = 2 MACE_OUT_OF_RESOURCES = 2,
MACE_UNSUPPORTED = 3,
MACE_RUNTIME_ERROR = 4,
}; };
public: public:
...@@ -167,18 +169,6 @@ class MaceStatus { ...@@ -167,18 +169,6 @@ class MaceStatus {
std::unique_ptr<Impl> impl_; std::unique_ptr<Impl> 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. /// \brief GPU context contain the status used for GPU device.
/// ///
/// There are some data in common between different MaceEngines using GPU, /// There are some data in common between different MaceEngines using GPU,
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include <sstream>
#include "mace/public/mace.h" #include "mace/public/mace.h"
namespace mace { namespace mace {
...@@ -26,10 +28,16 @@ class MaceStatus::Impl { ...@@ -26,10 +28,16 @@ class MaceStatus::Impl {
void SetCode(const Code code) { code_ = code; } void SetCode(const Code code) { code_ = code; }
Code code() const { return code_; } Code code() const { return code_; }
void SetInformation(const std::string &info) { information_ = info; } 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: private:
std::string Code2Str() const { std::string CodeToString() const {
switch (code_) { switch (code_) {
case MaceStatus::MACE_SUCCESS: case MaceStatus::MACE_SUCCESS:
return "Success"; return "Success";
...@@ -37,8 +45,14 @@ class MaceStatus::Impl { ...@@ -37,8 +45,14 @@ class MaceStatus::Impl {
return "Invalid Arguments"; return "Invalid Arguments";
case MaceStatus::MACE_OUT_OF_RESOURCES: case MaceStatus::MACE_OUT_OF_RESOURCES:
return "Out of resources"; return "Out of resources";
case MACE_UNSUPPORTED:
return "Unsupported";
case MACE_RUNTIME_ERROR:
return "Runtime error";
default: default:
return ""; std::ostringstream os;
os << code_;
return os.str();
} }
} }
......
...@@ -16,10 +16,10 @@ ...@@ -16,10 +16,10 @@
#include <string> #include <string>
#include "mace/core/macros.h" #include "mace/utils/macros.h"
#include "mace/proto/mace.pb.h" #include "mace/proto/mace.pb.h"
#include "mace/public/mace.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/logging.h"
namespace mace { namespace mace {
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "mace/proto/mace.pb.h" #include "mace/proto/mace.pb.h"
#include "mace/public/mace.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/logging.h"
namespace mace { namespace mace {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include "mace/proto/mace.pb.h" #include "mace/proto/mace.pb.h"
#include "mace/public/mace.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/logging.h"
namespace mace { namespace mace {
......
...@@ -24,8 +24,7 @@ ...@@ -24,8 +24,7 @@
* --model_data_file=model_data.data \ * --model_data_file=model_data.data \
* --device=GPU * --device=GPU
*/ */
#include <malloc.h> #include <cstdint>
#include <stdint.h>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <fstream> #include <fstream>
...@@ -34,9 +33,9 @@ ...@@ -34,9 +33,9 @@
#include "gflags/gflags.h" #include "gflags/gflags.h"
#include "mace/public/mace.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/logging.h"
#include "mace/utils/utils.h" #include "mace/utils/string_util.h"
#ifdef MODEL_GRAPH_FORMAT_CODE #ifdef MODEL_GRAPH_FORMAT_CODE
#include "mace/codegen/engine/mace_engine_factory.h" #include "mace/codegen/engine/mace_engine_factory.h"
...@@ -46,29 +45,6 @@ namespace mace { ...@@ -46,29 +45,6 @@ namespace mace {
namespace tools { namespace tools {
namespace validation { namespace validation {
namespace str_util {
std::vector<std::string> Split(const std::string &str, char delims) {
std::vector<std::string> 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<int64_t> *shape) { void ParseShape(const std::string &str, std::vector<int64_t> *shape) {
std::string tmp = str; std::string tmp = str;
while (!tmp.empty()) { while (!tmp.empty()) {
...@@ -500,13 +476,10 @@ int Main(int argc, char **argv) { ...@@ -500,13 +476,10 @@ int Main(int argc, char **argv) {
LOG(INFO) << "omp_num_threads: " << FLAGS_omp_num_threads; LOG(INFO) << "omp_num_threads: " << FLAGS_omp_num_threads;
LOG(INFO) << "cpu_affinity_policy: " << FLAGS_cpu_affinity_policy; LOG(INFO) << "cpu_affinity_policy: " << FLAGS_cpu_affinity_policy;
std::vector<std::string> input_names = str_util::Split(FLAGS_input_node, ','); std::vector<std::string> input_names = Split(FLAGS_input_node, ',');
std::vector<std::string> output_names = std::vector<std::string> output_names = Split(FLAGS_output_node, ',');
str_util::Split(FLAGS_output_node, ','); std::vector<std::string> input_shapes = Split(FLAGS_input_shape, ':');
std::vector<std::string> input_shapes = std::vector<std::string> output_shapes = Split(FLAGS_output_shape, ':');
str_util::Split(FLAGS_input_shape, ':');
std::vector<std::string> output_shapes =
str_util::Split(FLAGS_output_shape, ':');
const size_t input_count = input_shapes.size(); const size_t input_count = input_shapes.size();
const size_t output_count = output_shapes.size(); const size_t output_count = output_shapes.size();
......
...@@ -7,12 +7,6 @@ package( ...@@ -7,12 +7,6 @@ package(
licenses(["notice"]) # Apache 2.0 licenses(["notice"]) # Apache 2.0
load(
"//mace:mace.bzl",
"if_android",
"if_openmp_enabled",
)
cc_library( cc_library(
name = "utils", name = "utils",
srcs = glob( srcs = glob(
...@@ -20,7 +14,7 @@ cc_library( ...@@ -20,7 +14,7 @@ cc_library(
"*.cc", "*.cc",
], ],
exclude = [ exclude = [
"tuner_test.cc", "*_test.cc",
], ],
), ),
hdrs = glob([ hdrs = glob([
...@@ -30,36 +24,30 @@ cc_library( ...@@ -30,36 +24,30 @@ cc_library(
"-Werror", "-Werror",
"-Wextra", "-Wextra",
"-Wno-missing-field-initializers", "-Wno-missing-field-initializers",
] + if_openmp_enabled([ ],
"-fopenmp",
]),
linkopts = if_android([
"-llog",
]),
deps = [ deps = [
"//mace/port:port_api",
"//mace/public", "//mace/public",
], ],
) )
cc_test( cc_test(
name = "tuner_test", name = "utils_test",
testonly = 1, testonly = 1,
srcs = [ srcs = glob(
"tuner_test.cc", [
"*_test.cc",
], ],
),
copts = [ copts = [
"-Werror", "-Werror",
"-Wextra", "-Wextra",
"-Wno-missing-field-initializers", "-Wno-missing-field-initializers",
], ],
linkopts = ["-ldl"] + if_android([ linkstatic = 0,
"-pie",
"-lm", # Required by unordered_map
]),
linkstatic = 1,
deps = [ deps = [
":utils", ":utils",
"//mace/core", "//mace/port",
"@gtest//:gtest", "@gtest//:gtest",
"@gtest//:gtest_main", "@gtest//:gtest_main",
], ],
......
// 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 <algorithm>
#include <cstdlib>
#include <map>
#include <string>
#include <vector>
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_
// 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 <algorithm>
#include <cmath>
#include <functional>
#include <memory>
#include <utility>
#include <vector>
#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<BBox> &bboxes,
const float nms_threshold,
const int top_k,
std::vector<BBox> *sorted_boxes) {
const int n = std::min(top_k, static_cast<int>(bboxes.size()));
std::vector<int> picked;
std::vector<float> 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> *bbox_rects) {
MACE_CHECK(keep_top_k > 0, "keep_top_k should be greater than 0");
std::vector<float> 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<BBox> 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<BBox> sorted_boxes;
NmsSortedBboxes(class_bbox_rects,
nms_threshold,
std::min(top_k,
static_cast<int>(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<int>(bbox_rects->size()) ?
keep_top_k : static_cast<int>(bbox_rects->size());
bbox_rects->resize(num_detected);
return num_detected;
}
} // namespace mace
// 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"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
...@@ -21,45 +21,19 @@ ...@@ -21,45 +21,19 @@
#include <vector> #include <vector>
#include <utility> #include <utility>
#include "mace/public/mace.h" #include "mace/port/env.h"
#include "mace/utils/env_time.h" #include "mace/port/logger.h"
#include "mace/utils/macros.h"
#include "mace/utils/string_util.h" #include "mace/utils/string_util.h"
#include "mace/utils/utils.h"
#undef ERROR
namespace mace { namespace mace {
namespace logging_internal {
// 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_;
};
#define LOG(severity) \ #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. #define VLOG_IS_ON(vll) (mace::ShouldGenerateVLogMessage(vll))
// Only when vlog_level <= MinVLogLevel(), it will produce output.
#define VLOG_IS_ON(vll) ((vll) <= ::mace::logging::LogMessage::MinVLogLevel())
#define VLOG(vll) if (VLOG_IS_ON(vll)) LOG(INFO) #define VLOG(vll) if (VLOG_IS_ON(vll)) LOG(INFO)
// MACE_CHECK/MACE_ASSERT dies with a fatal error if condition is not true. // MACE_CHECK/MACE_ASSERT dies with a fatal error if condition is not true.
...@@ -85,17 +59,27 @@ class LogMessage : public std::ostringstream { ...@@ -85,17 +59,27 @@ class LogMessage : public std::ostringstream {
template <typename T> template <typename T>
T &&CheckNotNull(const char *file, int line, const char *exprtext, T &&t) { T &&CheckNotNull(const char *file, int line, const char *exprtext, T &&t) {
if (t == nullptr) { 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>(t); return std::forward<T>(t);
} }
#define MACE_CHECK_NOTNULL(val) \ #define MACE_CHECK_NOTNULL(val) \
::mace::logging::CheckNotNull(__FILE__, __LINE__, \ ::mace::logging_internal::CheckNotNull(__FILE__, __LINE__, \
"'" #val "' Must not be NULL", (val)) "'" #val "' Must not be NULL", (val))
#define MACE_NOT_IMPLEMENTED MACE_CHECK(false, "not implemented") #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 { class LatencyLogger {
public: public:
LatencyLogger(int vlog_level, const std::string &message) LatencyLogger(int vlog_level, const std::string &message)
...@@ -122,10 +106,20 @@ class LatencyLogger { ...@@ -122,10 +106,20 @@ class LatencyLogger {
}; };
#define MACE_LATENCY_LOGGER(vlog_level, ...) \ #define MACE_LATENCY_LOGGER(vlog_level, ...) \
mace::logging::LatencyLogger latency_logger_##__line__( \ mace::logging_internal::LatencyLogger latency_logger_##__line__( \
vlog_level, VLOG_IS_ON(vlog_level) ? mace::MakeString(__VA_ARGS__) : "") 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 } // namespace mace
#endif // MACE_UTILS_LOGGING_H_ #endif // MACE_UTILS_LOGGING_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/utils/logging.h"
#include <gtest/gtest.h>
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
// 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"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
...@@ -12,8 +12,27 @@ ...@@ -12,8 +12,27 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef MACE_CORE_MACROS_H_ #ifndef MACE_UTILS_MACROS_H_
#define MACE_CORE_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 // 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. // instance, a CHECK failure), and use that information in static analysis.
...@@ -27,6 +46,6 @@ ...@@ -27,6 +46,6 @@
#define MACE_PREDICT_TRUE(x) (x) #define MACE_PREDICT_TRUE(x) (x)
#endif #endif
#define MACE_UNUSED(var) (void)(var) } // namespace mace
#endif // MACE_CORE_MACROS_H_ #endif // MACE_UTILS_MACROS_H_
...@@ -12,31 +12,17 @@ ...@@ -12,31 +12,17 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef MACE_UTILS_UTILS_H_ #ifndef MACE_UTILS_MATH_H_
#define MACE_UTILS_UTILS_H_ #define MACE_UTILS_MATH_H_
#include <algorithm>
#include <cstdlib>
#include <cmath> #include <cmath>
#include <map>
#include <string>
#include <vector>
namespace mace { #include <algorithm>
#include <vector>
// Disable the copy and assignment operator for a class. #include "mace/utils/logging.h"
#ifndef MACE_DISABLE_COPY_AND_ASSIGN
#define MACE_DISABLE_COPY_AND_ASSIGN(CLASSNAME) \
private: \
CLASSNAME(const CLASSNAME &) = delete; \
CLASSNAME &operator=(const CLASSNAME &) = delete
#endif
#ifndef MACE_EMPTY_VIRTUAL_DESTRUCTOR namespace mace {
#define MACE_EMPTY_VIRTUAL_DESTRUCTOR(CLASSNAME) \
public: \
virtual ~CLASSNAME() {}
#endif
template <typename Integer> template <typename Integer>
Integer RoundUp(Integer i, Integer factor) { Integer RoundUp(Integer i, Integer factor) {
...@@ -69,8 +55,6 @@ Integer CeilQuotient(Integer a, Integer b) { ...@@ -69,8 +55,6 @@ Integer CeilQuotient(Integer a, Integer b) {
return (a + b - 1) / b; return (a + b - 1) / b;
} }
std::string ObfuscateString(const std::string &src,
const std::string &lookup_table);
template <typename Integer> template <typename Integer>
inline Integer Clamp(Integer in, Integer low, Integer high) { inline Integer Clamp(Integer in, Integer low, Integer high) {
return std::max<Integer>(low, std::min<Integer>(in, high)); return std::max<Integer>(low, std::min<Integer>(in, high));
...@@ -98,48 +82,11 @@ inline T ScalarTanh(T in) { ...@@ -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<std::string> Split(const std::string &str, char delims);
bool ReadBinaryFile(std::vector<unsigned char> *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 <typename T>
std::vector<std::string> MapKeys(const std::map<std::string, T> &data) {
std::vector<std::string> 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 <typename SrcType, typename DstType> template <typename SrcType, typename DstType>
std::vector<DstType> TransposeShape(const std::vector<SrcType> &shape, std::vector<DstType> TransposeShape(const std::vector<SrcType> &shape,
const std::vector<int> &dst_dims) { const std::vector<int> &dst_dims) {
size_t shape_dims = shape.size(); size_t shape_dims = shape.size();
MACE_CHECK(shape_dims == dst_dims.size());
std::vector<DstType> output_shape(shape_dims); std::vector<DstType> output_shape(shape_dims);
for (size_t i = 0; i < shape_dims; ++i) { for (size_t i = 0; i < shape_dims; ++i) {
output_shape[i] = static_cast<DstType>(shape[dst_dims[i]]); output_shape[i] = static_cast<DstType>(shape[dst_dims[i]]);
...@@ -148,4 +95,5 @@ std::vector<DstType> TransposeShape(const std::vector<SrcType> &shape, ...@@ -148,4 +95,5 @@ std::vector<DstType> TransposeShape(const std::vector<SrcType> &shape,
} }
} // namespace mace } // namespace mace
#endif // MACE_UTILS_UTILS_H_
#endif // MACE_UTILS_MATH_H_
// 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 <malloc.h>
#endif
#include <string>
#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_
...@@ -17,7 +17,9 @@ ...@@ -17,7 +17,9 @@
#include <condition_variable> // NOLINT(build/c++11) #include <condition_variable> // NOLINT(build/c++11)
#include <mutex> // NOLINT(build/c++11) #include <mutex> // NOLINT(build/c++11)
#include "mace/utils/logging.h" #include "mace/utils/logging.h"
#include "mace/utils/macros.h"
namespace mace { namespace mace {
namespace utils { namespace utils {
...@@ -26,10 +28,6 @@ class RWMutex { ...@@ -26,10 +28,6 @@ class RWMutex {
public: public:
RWMutex() : counter_(0), waiting_readers_(0), waiting_writers_(0) {} RWMutex() : counter_(0), waiting_readers_(0), waiting_writers_(0) {}
~RWMutex() = default; ~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 counter_; // -1 for writer, 0 for nobody, 1~n for reader
int waiting_readers_; int waiting_readers_;
...@@ -37,6 +35,8 @@ class RWMutex { ...@@ -37,6 +35,8 @@ class RWMutex {
std::mutex mutex_; std::mutex mutex_;
std::condition_variable reader_cv_; std::condition_variable reader_cv_;
std::condition_variable writer_cv_; std::condition_variable writer_cv_;
MACE_DISABLE_COPY_AND_ASSIGN(RWMutex);
}; };
// Writer first // Writer first
...@@ -61,13 +61,11 @@ class ReadLock { ...@@ -61,13 +61,11 @@ class ReadLock {
} }
} }
} }
ReadLock(const ReadLock &) = delete;
ReadLock(ReadLock &&) = delete;
ReadLock& operator=(const ReadLock &) = delete;
ReadLock& operator=(ReadLock &&) = delete;
private: private:
RWMutex *rw_mutex_; RWMutex *rw_mutex_;
MACE_DISABLE_COPY_AND_ASSIGN(ReadLock);
}; };
class WriteLock { class WriteLock {
...@@ -91,13 +89,11 @@ class WriteLock { ...@@ -91,13 +89,11 @@ class WriteLock {
rw_mutex_->reader_cv_.notify_all(); rw_mutex_->reader_cv_.notify_all();
} }
} }
WriteLock(const WriteLock &) = delete;
WriteLock(WriteLock &&) = delete;
WriteLock& operator=(const WriteLock &) = delete;
WriteLock& operator=(WriteLock &&) = delete;
private: private:
RWMutex *rw_mutex_; RWMutex *rw_mutex_;
MACE_DISABLE_COPY_AND_ASSIGN(WriteLock);
}; };
} // namespace utils } // namespace utils
......
// 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 <algorithm>
#include <cstdlib>
#include <map>
#include <string>
#include <vector>
namespace mace {
template <typename T>
std::vector<std::string> MapKeys(const std::map<std::string, T> &data) {
std::vector<std::string> keys;
for (auto &kv : data) {
keys.push_back(kv.first);
}
return keys;
}
} // namespace mace
#endif // MACE_UTILS_STL_UTIL_H_
...@@ -83,4 +83,65 @@ std::string StringFormatter::Table( ...@@ -83,4 +83,65 @@ std::string StringFormatter::Table(
} }
} // namespace string_util } // 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<std::string> Split(const std::string &str, char delims) {
std::vector<std::string> 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 } // namespace mace
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#ifndef MACE_UTILS_STRING_UTIL_H_ #ifndef MACE_UTILS_STRING_UTIL_H_
#define MACE_UTILS_STRING_UTIL_H_ #define MACE_UTILS_STRING_UTIL_H_
#include <algorithm>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
...@@ -80,6 +81,35 @@ inline std::string MakeString(const std::string &str) { ...@@ -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 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<std::string> Split(const std::string &str, char delims);
} // namespace mace } // namespace mace
#endif // MACE_UTILS_STRING_UTIL_H_ #endif // MACE_UTILS_STRING_UTIL_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/utils/string_util.h"
#include <gtest/gtest.h>
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
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#ifndef MACE_UTILS_TIMER_H_ #ifndef MACE_UTILS_TIMER_H_
#define 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" #include "mace/utils/logging.h"
namespace mace { namespace mace {
......
...@@ -14,12 +14,14 @@ ...@@ -14,12 +14,14 @@
#ifndef MACE_UTILS_TUNER_H_ #ifndef MACE_UTILS_TUNER_H_
#define MACE_UTILS_TUNER_H_ #define MACE_UTILS_TUNER_H_
// TODO(heliangliang) Fix portability
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <cstdlib>
#include <cstring> #include <cstring>
#include <fstream> #include <fstream>
#include <functional> #include <functional>
...@@ -30,8 +32,8 @@ ...@@ -30,8 +32,8 @@
#include <vector> #include <vector>
#include "mace/utils/logging.h" #include "mace/utils/logging.h"
#include "mace/utils/string_util.h"
#include "mace/utils/timer.h" #include "mace/utils/timer.h"
#include "mace/utils/utils.h"
namespace mace { namespace mace {
...@@ -293,4 +295,5 @@ class Tuner { ...@@ -293,4 +295,5 @@ class Tuner {
}; };
} // namespace mace } // namespace mace
#endif // MACE_UTILS_TUNER_H_ #endif // MACE_UTILS_TUNER_H_
// 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 <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <cerrno>
#include <cstring>
#include <fstream>
#include <map>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#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<std::string> Split(const std::string &str, char delims) {
std::vector<std::string> 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<unsigned char> *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<char *>(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<size_t>(st.st_size);
if (*size == 0) {
return;
}
*data = static_cast<const unsigned char *>(
mmap(nullptr, *size, PROT_READ, MAP_PRIVATE, fd, 0));
MACE_CHECK(*data != static_cast<const unsigned char *>(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<unsigned char *>(data), size);
MACE_CHECK(ret == 0,
"Failed to unmap file, error code: ", strerror(errno));
}
} // namespace mace
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
""" """
def _git_version_conf_impl(repository_ctx): def _git_version_conf_impl(repository_ctx):
repository_ctx.template( repository_ctx.template(
"BUILD", "BUILD.bazel",
Label("//repository/git:BUILD.tpl")) 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") generated_files_path = repository_ctx.path("gen")
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
def _opencl_encrypt_kernel_impl(repository_ctx): def _opencl_encrypt_kernel_impl(repository_ctx):
repository_ctx.template( repository_ctx.template(
"BUILD", "BUILD.bazel",
Label("//repository/opencl-kernel:BUILD.tpl"), 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") generated_files_path = repository_ctx.path("gen")
ret = repository_ctx.execute( ret = repository_ctx.execute(
......
...@@ -14,6 +14,9 @@ build --copt=-DGEMMLOWP_USE_OPENMP ...@@ -14,6 +14,9 @@ build --copt=-DGEMMLOWP_USE_OPENMP
build:symbol_hidden --copt=-fvisibility=hidden build:symbol_hidden --copt=-fvisibility=hidden
# Usage example: bazel build --config android # 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 --distinct_host_configuration=true
build:android --crosstool_top=//external:android/crosstool build:android --crosstool_top=//external:android/crosstool
build:android --host_crosstool_top=@bazel_tools//tools/cpp:toolchain build:android --host_crosstool_top=@bazel_tools//tools/cpp:toolchain
......
...@@ -118,8 +118,8 @@ def parse_args(): ...@@ -118,8 +118,8 @@ def parse_args():
'--device_yml', '--device_yml',
type=str, type=str,
default='', 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() return parser.parse_known_args()
...@@ -130,7 +130,9 @@ def main(unused_args): ...@@ -130,7 +130,9 @@ def main(unused_args):
for target_abi in target_abis: for target_abi in target_abis:
toolchain = infer_toolchain(target_abi) toolchain = infer_toolchain(target_abi)
sh_commands.bazel_build(target, abi=target_abi, sh_commands.bazel_build(
target,
abi=target_abi,
toolchain=toolchain, toolchain=toolchain,
enable_neon=FLAGS.enable_neon, enable_neon=FLAGS.enable_neon,
address_sanitizer=FLAGS.address_sanitizer) address_sanitizer=FLAGS.address_sanitizer)
...@@ -158,12 +160,11 @@ def main(unused_args): ...@@ -158,12 +160,11 @@ def main(unused_args):
bin_name, bin_name,
args=FLAGS.args, args=FLAGS.args,
opencl_profiling=True, opencl_profiling=True,
vlog_level=0, vlog_level=FLAGS.vlog_level,
out_of_range_check=True, out_of_range_check=True,
address_sanitizer=FLAGS.address_sanitizer, address_sanitizer=FLAGS.address_sanitizer,
simpleperf=FLAGS.simpleperf) simpleperf=FLAGS.simpleperf)
globals()[FLAGS.stdout_processor](stdouts, dev, globals()[FLAGS.stdout_processor](stdouts, dev, target_abi)
target_abi)
if __name__ == "__main__": if __name__ == "__main__":
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册