Skip to content

Commit 83f4e9e

Browse files
hjchen2qingqing01
authored andcommitted
enable eigen multi-threads on mobile device (#10938)
1 parent 0930646 commit 83f4e9e

File tree

4 files changed

+87
-8
lines changed

4 files changed

+87
-8
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ option(GLIDE_INSTALL "Download and install go dependencies " ON)
5757
option(USE_NNPACK "Compile PaddlePaddle with NNPACK library" OFF)
5858
option(WITH_DISTRIBUTE "Compile with grpc distributed support" OFF)
5959
option(USE_EIGEN_FOR_BLAS "Use matrix multiplication in Eigen" OFF)
60+
option(EIGEN_USE_THREADS "Compile with multi-threaded Eigen" OFF)
6061
option(WITH_ARM_FP16 "Use half precision support on armv8.2-a cpu" OFF)
6162
option(WITH_FAST_BUNDLE_TEST "Bundle tests that can be run in a single process together to reduce launch overhead" OFF)
6263
option(WITH_CONTRIB "Compile the third-party contributation" OFF)

cmake/configure.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ if(USE_EIGEN_FOR_BLAS)
4141
add_definitions(-DPADDLE_USE_EIGEN_FOR_BLAS)
4242
endif(USE_EIGEN_FOR_BLAS)
4343

44+
if(EIGEN_USE_THREADS)
45+
add_definitions(-DEIGEN_USE_THREADS)
46+
endif(EIGEN_USE_THREADS)
47+
4448
if(NOT WITH_PROFILER)
4549
add_definitions(-DPADDLE_DISABLE_PROFILER)
4650
endif(NOT WITH_PROFILER)

paddle/function/EigenGemm.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
1313
limitations under the License. */
1414

1515
#include <glog/logging.h>
16-
#include "unsupported/Eigen/CXX11/Tensor"
16+
#include "paddle/function/EigenThreadDevice.h"
1717

1818
namespace paddle {
1919

@@ -70,25 +70,26 @@ struct EigenBlasGemm {
7070
dims[0].first = transA ? 0 : 1;
7171
dims[0].second = transB ? 1 : 0;
7272

73-
Eigen::DefaultDevice device;
73+
auto* device = EigenDeviceWarpper::device();
7474
if (N == ldc) {
7575
if (alpha == T(1) && beta == T(0)) {
76-
c.device(device) = a.contract(b, dims);
76+
c.device(*device) = a.contract(b, dims);
7777
} else if (alpha == T(1) && beta == T(1)) {
78-
c.device(device) += a.contract(b, dims);
78+
c.device(*device) += a.contract(b, dims);
7979
} else {
80-
c.device(device) = alpha * a.contract(b, dims) + beta * c;
80+
c.device(*device) = alpha * a.contract(b, dims) + beta * c;
8181
}
8282
} else {
8383
if (alpha == T(1) && beta == T(0)) {
84-
c.slice(offsetC, extentC).device(device) = a.contract(b, dims);
84+
c.slice(offsetC, extentC).device(*device) = a.contract(b, dims);
8585
} else if (alpha == T(1) && beta == T(1)) {
86-
c.slice(offsetC, extentC).device(device) += a.contract(b, dims);
86+
c.slice(offsetC, extentC).device(*device) += a.contract(b, dims);
8787
} else {
88-
c.slice(offsetC, extentC).device(device) =
88+
c.slice(offsetC, extentC).device(*device) =
8989
alpha * a.contract(b, dims) + beta * c.slice(offsetC, extentC);
9090
}
9191
}
92+
EigenDeviceWarpper::free_device(device);
9293
}
9394
};
9495

paddle/function/EigenThreadDevice.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License. */
14+
15+
#pragma once
16+
17+
#if defined(__OSX__) || defined(__APPLE__)
18+
#include <sys/sysctl.h>
19+
#include <sys/types.h>
20+
#endif
21+
#include "unsupported/Eigen/CXX11/Tensor"
22+
23+
namespace paddle {
24+
25+
#if defined(__ANDROID__)
26+
int GetCpuCount() {
27+
FILE* fp = fopen("/sys/devices/system/cpu/possible", "r");
28+
if (!fp) {
29+
return 1;
30+
}
31+
int rank0, rank1;
32+
int num = fscanf(fp, "%d-%d", &rank0, &rank1);
33+
fclose(fp);
34+
if (num < 2) return 1;
35+
return rank1 + 1;
36+
}
37+
#elif defined(__OSX__) || defined(__APPLE__)
38+
int GetCpuCount() {
39+
int count = 0;
40+
size_t len = sizeof(int);
41+
sysctlbyname("hw.ncpu", &count, &len, NULL, 0);
42+
return count > 0 ? count : 1;
43+
}
44+
#else
45+
int GetCpuCount() { return 1; }
46+
#endif
47+
48+
class EigenDeviceWarpper {
49+
public: // NOLINT
50+
#if EIGEN_USE_THREADS
51+
static Eigen::ThreadPoolDevice* device() {
52+
const int num_cpus = GetCpuCount();
53+
const int num_threads = (num_cpus > 2) ? 2 : num_cpus;
54+
static Eigen::ThreadPool tp(num_threads);
55+
static Eigen::ThreadPoolDevice* device =
56+
new Eigen::ThreadPoolDevice(&tp, num_threads);
57+
return device;
58+
}
59+
60+
static void free_device(Eigen::ThreadPoolDevice* device) {
61+
// do nothing
62+
}
63+
#else
64+
static Eigen::DefaultDevice* device() {
65+
Eigen::DefaultDevice* device = new Eigen::DefaultDevice;
66+
return device;
67+
}
68+
69+
static void free_device(Eigen::DefaultDevice* device) { delete device; }
70+
#endif
71+
};
72+
73+
} // namespace paddle

0 commit comments

Comments
 (0)