1{
2 stdenv,
3 lib,
4 fetchFromGitHub,
5 fetchurl,
6 fetchpatch,
7 cmake,
8 boost,
9 gflags,
10 glog,
11 hdf5-cpp,
12 opencv4,
13 protobuf,
14 doxygen,
15 blas,
16 lmdbSupport ? true,
17 lmdb,
18 leveldbSupport ? true,
19 leveldb,
20 snappy,
21 pythonSupport ? false,
22 python ? null,
23 numpy ? null,
24 replaceVars,
25}:
26
27let
28 toggle = bool: if bool then "ON" else "OFF";
29
30 test_model_weights = fetchurl {
31 url = "http://dl.caffe.berkeleyvision.org/bvlc_reference_caffenet.caffemodel";
32 sha256 = "472d4a06035497b180636d8a82667129960371375bd10fcb6df5c6c7631f25e0";
33 };
34in
35
36stdenv.mkDerivation rec {
37 pname = "caffe";
38 version = "1.0";
39
40 src = fetchFromGitHub {
41 owner = "BVLC";
42 repo = "caffe";
43 rev = version;
44 sha256 = "104jp3cm823i3cdph7hgsnj6l77ygbwsy35mdmzhmsi4jxprd9j3";
45 };
46
47 nativeBuildInputs = [
48 cmake
49 doxygen
50 ];
51
52 cmakeFlags =
53 # It's important that caffe is passed the major and minor version only because that's what
54 # boost_python expects
55 [
56 (if pythonSupport then "-Dpython_version=${python.pythonVersion}" else "-DBUILD_python=OFF")
57 "-DBLAS=open"
58 "-DCPU_ONLY=ON"
59 ]
60 ++ [ "-DUSE_LEVELDB=${toggle leveldbSupport}" ]
61 ++ [ "-DUSE_LMDB=${toggle lmdbSupport}" ];
62
63 buildInputs = [
64 boost
65 gflags
66 glog
67 protobuf
68 hdf5-cpp
69 opencv4
70 blas
71 ]
72 ++ lib.optional lmdbSupport lmdb
73 ++ lib.optionals leveldbSupport [
74 leveldb
75 snappy
76 ]
77 ++ lib.optionals pythonSupport [
78 python
79 numpy
80 ];
81
82 propagatedBuildInputs = lib.optionals pythonSupport (
83 # requirements.txt
84 let
85 pp = python.pkgs;
86 in
87 (
88 [
89 pp.numpy
90 pp.scipy
91 pp.scikit-image
92 pp.h5py
93 pp.matplotlib
94 pp.ipython
95 pp.networkx
96 pp.pandas
97 pp.python-dateutil
98 pp.protobuf
99 pp.gflags
100 pp.pyyaml
101 pp.pillow
102 pp.six
103 ]
104 ++ lib.optional leveldbSupport pp.leveldb
105 )
106 );
107
108 outputs = [
109 "bin"
110 "out"
111 ];
112 propagatedBuildOutputs = [ ]; # otherwise propagates out -> bin cycle
113
114 patches = [
115 ./darwin.patch
116 ./glog-cmake.patch
117 ./random-shuffle.patch
118 (fetchpatch {
119 name = "support-opencv4";
120 url = "https://github.com/BVLC/caffe/pull/6638/commits/0a04cc2ccd37ba36843c18fea2d5cbae6e7dd2b5.patch";
121 hash = "sha256-ZegTvp0tTHlopQv+UzHDigs6XLkP2VfqLCWXl6aKJSI=";
122 })
123 ]
124 ++ lib.optional pythonSupport (
125 replaceVars ./python.patch {
126 inherit (python.sourceVersion) major minor; # Should be changed in case of PyPy
127 }
128 );
129
130 postPatch = ''
131 substituteInPlace src/caffe/util/io.cpp --replace \
132 'SetTotalBytesLimit(kProtoReadBytesLimit, 536870912)' \
133 'SetTotalBytesLimit(kProtoReadBytesLimit)'
134 '';
135
136 preConfigure = lib.optionalString pythonSupport ''
137 # We need this when building with Python bindings
138 export BOOST_LIBRARYDIR="${boost.out}/lib";
139 '';
140
141 postInstall = ''
142 # Internal static library.
143 rm $out/lib/libproto.a
144
145 # Install models
146 cp -a ../models $out/share/Caffe/models
147
148 moveToOutput "bin" "$bin"
149 ''
150 + lib.optionalString pythonSupport ''
151 mkdir -p $out/${python.sitePackages}
152 mv $out/python/caffe $out/${python.sitePackages}
153 rm -rf $out/python
154 '';
155
156 doInstallCheck = false; # build takes more than 30 min otherwise
157 installCheckPhase = ''
158 model=bvlc_reference_caffenet
159 m_path="$out/share/Caffe/models/$model"
160 $bin/bin/caffe test \
161 -model "$m_path/deploy.prototxt" \
162 -solver "$m_path/solver.prototxt" \
163 -weights "${test_model_weights}"
164 '';
165
166 meta = with lib; {
167 description = "Deep learning framework";
168 longDescription = ''
169 Caffe is a deep learning framework made with expression, speed, and
170 modularity in mind. It is developed by the Berkeley Vision and Learning
171 Center (BVLC) and by community contributors.
172 '';
173 homepage = "http://caffe.berkeleyvision.org/";
174 maintainers = [ ];
175 broken =
176 (pythonSupport && (python.isPy310))
177 || !(leveldbSupport -> (leveldb != null && snappy != null))
178 || !(pythonSupport -> (python != null && numpy != null));
179 license = licenses.bsd2;
180 platforms = platforms.linux ++ platforms.darwin;
181 };
182}