Skip to content

Commit 22088dd

Browse files
authored
Merge pull request #362 from Necross/coremltools3.0b
Consolidating changes for coremltools3.0 beta release
2 parents 8308ea8 + 05a2f70 commit 22088dd

File tree

239 files changed

+151609
-30139
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

239 files changed

+151609
-30139
lines changed

CMakeLists.txt

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
cmake_minimum_required(VERSION 3.0.0)
1+
cmake_minimum_required(VERSION 3.12.0)
22

33
set(CMAKE_OSX_ARCHITECTURES x86_64)
44

@@ -13,34 +13,12 @@ endif()
1313
add_subdirectory(deps)
1414
add_subdirectory(mlmodel)
1515

16-
if("${PYTHON}" STREQUAL "")
17-
find_program(PYTHON NAMES python3 python)
18-
endif()
19-
if("${PYTHON_MAJOR_VERSION}" STREQUAL "")
20-
exec_program(${PYTHON}
21-
ARGS "-c 'import sys; print(sys.version_info.major)'"
22-
OUTPUT_VARIABLE PYTHON_MAJOR_VERSION)
23-
endif()
24-
if("${PYTHON_MINOR_VERSION}" STREQUAL "")
25-
exec_program(${PYTHON}
26-
ARGS "-c 'import sys; print(sys.version_info.minor)'"
27-
OUTPUT_VARIABLE PYTHON_MINOR_VERSION)
28-
endif()
29-
if("${PYTHON_VERSION}" STREQUAL "")
30-
set(PYTHON_VERSION "${PYTHON_MAJOR_VERSION}.${PYTHON_MINOR_VERSION}")
31-
endif()
32-
33-
if("${PYTHON_CONFIG}" STREQUAL "")
34-
find_program(PYTHON_CONFIG NAMES python3-config python-config)
35-
endif()
36-
exec_program(${PYTHON_CONFIG}
37-
ARGS "--includes"
38-
OUTPUT_VARIABLE PYTHON_CFLAGS)
16+
find_package(PythonInterp)
17+
find_package(PythonLibs)
3918

40-
message("Found python at ${PYTHON}")
41-
message("Found python version ${PYTHON_VERSION}")
42-
message("Found python-config at ${PYTHON_CONFIG}")
43-
message("Found python includes ${PYTHON_CFLAGS}")
19+
message("Found python at ${PYTHON_EXECUTABLE}")
20+
message("Found python version ${PYTHON_VERSION_STRING}")
21+
message("Found python includes ${PYTHON_INCLUDE_DIRS}")
4422

4523
include_directories(
4624
.
@@ -49,11 +27,11 @@ include_directories(
4927
deps/protobuf/src
5028
deps/pybind11/include
5129
mlmodel/src
30+
${PYTHON_INCLUDE_DIRS}
5231
)
5332

5433
set(CMAKE_CXX_FLAGS " \
5534
${CMAKE_CXX_FLAGS} \
56-
${PYTHON_CFLAGS} \
5735
--std=c++14 \
5836
")
5937

@@ -127,6 +105,16 @@ if (APPLE)
127105
set_target_properties(caffeconverter PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
128106
endif()
129107

108+
file(COPY ${CMAKE_SOURCE_DIR}/README.rst DESTINATION ${CMAKE_BINARY_DIR})
109+
file(COPY ${CMAKE_SOURCE_DIR}/coremltools/__init__.py
110+
DESTINATION ${CMAKE_BINARY_DIR}/coremltools)
111+
file(COPY ${CMAKE_SOURCE_DIR}/coremltools/__main__.py
112+
DESTINATION ${CMAKE_BINARY_DIR}/coremltools)
113+
set(copy_dirs _deps _scripts converters graph_visualization models proto)
114+
foreach(cdir IN ITEMS ${copy_dirs})
115+
file(COPY ${CMAKE_SOURCE_DIR}/coremltools/${cdir}
116+
DESTINATION ${CMAKE_BINARY_DIR}/coremltools)
117+
endforeach()
130118
if(APPLE)
131119
add_custom_command(
132120
TARGET caffeconverter
@@ -147,14 +135,14 @@ find_library(FOUNDATION Foundation)
147135

148136
if (APPLE AND CORE_VIDEO AND CORE_ML AND FOUNDATION)
149137
execute_process(
150-
COMMAND ${PYTHON} -c "import numpy; print(numpy.get_include())"
138+
COMMAND ${PYTHON_EXECUTABLE} -c "import numpy; print(numpy.get_include())"
151139
RESULT_VARIABLE NUMPY_INCLUDE_STATUS
152-
OUTPUT_VARIABLE NUMPY_INCLUDE)
140+
OUTPUT_VARIABLE NUMPY_INCLUDE
141+
)
153142

154143
if("${NUMPY_INCLUDE}" STREQUAL "" OR NOT NUMPY_INCLUDE_STATUS EQUAL 0)
155144
message(FATAL_ERROR "Could not find numpy include path. Exit code: ${NUMPY_INCLUDE_STATUS}")
156145
endif()
157-
158146
message("Found numpy include path at ${NUMPY_INCLUDE}")
159147

160148
include_directories(
@@ -175,6 +163,7 @@ if (APPLE AND CORE_VIDEO AND CORE_ML AND FOUNDATION)
175163
${CORE_VIDEO}
176164
${CORE_ML}
177165
${FOUNDATION}
166+
${PYTHON_LIBRARIES}
178167
)
179168

180169
if (APPLE)
@@ -193,22 +182,33 @@ else()
193182
message(STATUS "CoreML.framework and dependent frameworks not found. Skipping libcoremlpython build.")
194183
endif()
195184

196-
set(PYTHON_TAG "cp${PYTHON_MAJOR_VERSION}${PYTHON_MINOR_VERSION}")
185+
set(PYTHON_TAG "cp${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}")
197186
if(APPLE)
198-
set(PLAT_NAME "macosx_10_14_intel;macosx_10_13_intel;macosx_10_12_intel")
187+
set(PLAT_NAME "macosx_10_15_intel;macosx_10_14_intel;macosx_10_13_intel;macosx_10_12_intel")
199188
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
200189
set(PLAT_NAME "manylinux1_x86_64")
201190
else()
202191
message(FATAL_ERROR "Unsupported build platform. Supported platforms are Linux and macOS.")
203192
endif()
204193

205-
add_custom_target(dist
206-
# Workaround for building multiple platform versions since python setuptools only take in one platform via '--plat-name' argument
207-
# and cmake 'foreach' does not seem to work inside add_custom_target
208-
COMMAND for SUPP_PLATFORM in ${PLAT_NAME}$<SEMICOLON> do ${PYTHON} setup.py bdist_wheel --plat-name=$$SUPP_PLATFORM --python-tag=${PYTHON_TAG}$<SEMICOLON> done$<SEMICOLON>
209-
DEPENDS caffeconverter coremlpython
210-
COMMENT "Building Python wheel for coremltools under dist/"
211-
)
194+
# Add a target for each platform, and then a 'dist' that will build all of them.
195+
# Parallel invocations of setup.py is not safe, so we serialize them.
196+
set(plat_targets "")
197+
foreach(platform IN ITEMS ${PLAT_NAME})
198+
add_custom_target(dist_${platform}
199+
COMMENT "Building dist for platform ${platform}..."
200+
COMMAND ${PYTHON_EXECUTABLE}
201+
${CMAKE_SOURCE_DIR}/setup.py
202+
bdist_wheel
203+
--plat-name=${platform}
204+
--python-tag=${PYTHON_TAG}
205+
DEPENDS "caffeconverter;coremlpython;${plat_targets}"
206+
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
207+
)
208+
set(plat_targets "${plat_targets};dist_${platform}")
209+
endforeach()
210+
# Add a 'dist' target that will build wheels for all possible platforms.
211+
add_custom_target(dist DEPENDS ${plat_targets})
212212

213213
add_custom_target(pytest
214214
COMMAND pytest coremltools/test/

README.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,20 @@ Building from source
7070
To build the project, you need [CMake](https://cmake.org) to configure the project
7171

7272
```shell
73-
cmake .
73+
mkdir build
74+
cd build
75+
cmake ../
7476
```
7577

7678
When several python virtual environments are installed,
7779
it may be useful to use the following command instead,
7880
to point to the correct intended version of python:
7981

8082
```shell
81-
cmake . -DPYTHON=$(which python) -DPYTHON_CONFIG=$(which python-config)
83+
cmake \
84+
-DPYTHON_EXECUTABLE:FILEPATH=/Library/Frameworks/Python.framework/Versions/3.7/bin/python \
85+
-DPYTHON_INCLUDE_DIR=/Library/Frameworks/Python.framework/Versions/3.7/include/python3.7m \
86+
../
8287
```
8388

8489
after which you can use make to build the project
@@ -135,7 +140,10 @@ To install xgboost
135140

136141
```shell
137142
git clone --recursive https://github.com/dmlc/xgboost
138-
cd xgboost; cp make/minimum.mk ./config.mk; make
143+
cd xgboost
144+
git checkout v0.90
145+
git submodule update
146+
make config=make/config.mk -j8
139147
cd python-package; python setup.py develop
140148
```
141149

caffeconverter/Caffe/LSTM.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void CoreMLConverter::convertCaffeLSTM(CoreMLConverter::ConvertLayerParameters l
9090
//Copy weights
9191
//Input Weight Matrices
9292
int blobSize = caffeLayerWeights.blobs(0).data_size();
93-
int64_t expectedSize = 4*hidden_size*input_size;
93+
int64_t expectedSize = 4*((int64_t)hidden_size)*input_size;
9494
if (blobSize != expectedSize) {
9595
CoreMLConverter::errorInCaffeProto("Expected blob size = "+std::to_string(expectedSize)+" but found blob of size = "+std::to_string(blobSize)+" in caffe"
9696
, caffeLayer.name(), "Recurrent");
@@ -119,7 +119,7 @@ void CoreMLConverter::convertCaffeLSTM(CoreMLConverter::ConvertLayerParameters l
119119

120120
//biases
121121
blobSize = caffeLayerWeights.blobs(1).data_size();
122-
expectedSize = 4*hidden_size;
122+
expectedSize = 4*((int64_t)hidden_size);
123123
if (blobSize != expectedSize) {
124124
CoreMLConverter::errorInCaffeProto("Expected blob size = "+std::to_string(expectedSize)+" but found blob of size = "+std::to_string(blobSize)+" in caffe"
125125
, caffeLayer.name(), "Recurrent");
@@ -148,7 +148,7 @@ void CoreMLConverter::convertCaffeLSTM(CoreMLConverter::ConvertLayerParameters l
148148

149149
//Recursion matrices
150150
blobSize = caffeLayerWeights.blobs(2).data_size();
151-
expectedSize = 4*hidden_size*hidden_size;
151+
expectedSize = 4*((int64_t)hidden_size)*((int64_t)hidden_size);
152152
if (blobSize != expectedSize) {
153153
CoreMLConverter::errorInCaffeProto("Expected blob size = "+std::to_string(expectedSize)+" but found blob of size = "+std::to_string(blobSize)+" in caffe"
154154
, caffeLayer.name(), "Recurrent");

caffeconverter/Caffe/caffe_pb_wrapper.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
#pragma clang diagnostic ignored "-Wunused-parameter"
55
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
66
#pragma clang diagnostic ignored "-Wshadow"
7+
#if __apple_build_version__ < 10010028
78
#pragma clang diagnostic ignored "-Wextended-offsetof"
9+
#endif
810
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
911

1012
#include "caffe.pb.h"

caffeconverter/CaffeConverterLib.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void convertCaffe(const std::string& srcPath,
5353
caffe::NetParameter caffeWeightsNetwork;
5454
std::map<std::string, caffe::BlobProto> caffeMeanImageBlob;
5555

56-
// TODO: We need to use only one caffe network proto variable (rdar://problem/30400140)
56+
// TODO: We need to use only one caffe network proto variable
5757
// This is a workaround for that.
5858
if (caffeProtoTxtPath != "") {
5959
CoreMLConverter::loadCaffeNetwork(srcPath, caffeWeightsNetwork, caffeProtoTxtPath, caffeNetwork, meanImageProtoPath, caffeMeanImageBlob);

coremlpython/CoreMLPython.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#pragma clang diagnostic pop
77

88
#import <CoreML/CoreML.h>
9-
#import "NeuralNetworkShapes.hpp"
9+
#import "NeuralNetwork/NeuralNetworkShapes.hpp"
1010

1111
namespace py = pybind11;
1212

@@ -21,7 +21,7 @@ namespace CoreML {
2121
Model(const Model&) = delete;
2222
Model& operator=(const Model&) = delete;
2323
~Model();
24-
explicit Model(const std::string& urlStr);
24+
explicit Model(const std::string& urlStr, bool useCPUOnly);
2525
py::dict predict(const py::dict& input, bool useCPUOnly);
2626
static int32_t maximumSupportedSpecificationVersion();
2727
std::string toString() const;

coremlpython/CoreMLPython.mm

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#import "CoreMLPython.h"
44
#import "CoreMLPythonUtils.h"
55
#import "Globals.hpp"
6-
#import "NeuralNetworkShapes.hpp"
6+
#import "NeuralNetwork/NeuralNetworkShapes.hpp"
77
#import "Utils.hpp"
88

99
#pragma clang diagnostic push
@@ -25,7 +25,7 @@
2525
}
2626
}
2727

28-
Model::Model(const std::string& urlStr) {
28+
Model::Model(const std::string& urlStr, bool useCPUOnly) {
2929
@autoreleasepool {
3030

3131
// Compile the model
@@ -53,8 +53,16 @@
5353
errmsg << "\".";
5454
throw std::runtime_error(errmsg.str());
5555
}
56-
57-
m_model = [MLModel modelWithContentsOfURL:compiledUrl error:&error];
56+
57+
if (@available(macOS 10.14, *)) {
58+
MLModelConfiguration *configuration = [MLModelConfiguration new];
59+
if (useCPUOnly){
60+
configuration.computeUnits = MLComputeUnitsCPUOnly;
61+
}
62+
m_model = [MLModel modelWithContentsOfURL:compiledUrl configuration:configuration error:&error];
63+
} else {
64+
m_model = [MLModel modelWithContentsOfURL:compiledUrl error:&error];
65+
}
5866
Utils::handleError(error);
5967
}
6068
}
@@ -109,7 +117,7 @@
109117
py::module m("libcoremlpython", "CoreML.Framework Python bindings");
110118

111119
py::class_<Model>(m, "_MLModelProxy")
112-
.def(py::init<const std::string&>())
120+
.def(py::init<const std::string&, bool>())
113121
.def("predict", &Model::predict)
114122
.def_static("maximum_supported_specification_version", &Model::maximumSupportedSpecificationVersion);
115123

coremlpython/CoreMLPythonUtils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ namespace CoreML {
3434
py::object convertArrayValueToPython(MLMultiArray *value);
3535
py::object convertDictionaryValueToPython(NSDictionary<NSObject *,NSNumber *> * value);
3636
py::object convertImageValueToPython(CVPixelBufferRef value);
37-
37+
API_AVAILABLE(macos(10.14))
38+
py::object convertSequenceValueToPython(MLSequence *seq);
3839
py::dict shapeConstraintToPyDict(const ShapeConstraint& constraint);
3940

4041
}

0 commit comments

Comments
 (0)