tensorflow-metal-plugin 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tensorflow_metal_plugin-0.1.0/LICENSE +251 -0
- tensorflow_metal_plugin-0.1.0/MANIFEST.in +9 -0
- tensorflow_metal_plugin-0.1.0/Makefile +94 -0
- tensorflow_metal_plugin-0.1.0/PKG-INFO +273 -0
- tensorflow_metal_plugin-0.1.0/README.md +250 -0
- tensorflow_metal_plugin-0.1.0/setup.cfg +4 -0
- tensorflow_metal_plugin-0.1.0/setup.py +58 -0
- tensorflow_metal_plugin-0.1.0/src/plugin_init.cc +58 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_activation_ops.mm +554 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_alias_ops.mm +574 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_array_ops.mm +639 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_batch_norm_global_ops.mm +439 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_batch_norm_ops.mm +836 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_batch_space_ops.mm +727 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_bincount_ops.mm +274 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_box_proposal_ops.mm +366 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_collective_ops.mm +300 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_compare_ops.mm +806 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_conv3d_ops.mm +434 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_conv_generic_ops.mm +385 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_conv_ops.mm +487 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_crop_resize_ops.mm +448 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_ctc_ops.mm +334 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_cudnn_rnn_ops.mm +1207 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_debug_ops.mm +362 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_depthwise_ops.mm +548 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_dilation_ops.mm +518 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_dynamic_ops.mm +547 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_elementwise_ops.mm +857 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_extra_ops.mm +627 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_fft_ops.mm +667 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_fill_ops.mm +272 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_fused_ops.mm +637 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_gather_scatter_ops.mm +504 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_identity_op.mm +151 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_image2_ops.mm +624 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_image_ops.mm +327 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_index_ops.mm +689 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_inplace_ops.mm +302 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_kernel_util.h +166 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_kernel_util.mm +243 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_kernels.h +224 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_kernels.mm +96 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_linalg_ops.mm +661 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_matmul_op.mm +259 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_matrix_ops.mm +965 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_maxpool_argmax_ops.mm +525 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_misc2_ops.mm +466 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_misc_ops.mm +551 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_mps_graph.h +111 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_mps_graph.mm +304 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_nms_ops.mm +293 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_nn_ops.mm +685 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_pool_variant_ops.mm +429 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_pooling_ops.mm +330 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_quant_ops.mm +940 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_quantize_dequantize_ops.mm +707 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_random_dist_ops.mm +477 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_random_ops.mm +385 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_reduction_ops.mm +358 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_ref_variable_ops.mm +269 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_resize_grad_ops.mm +260 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_rnn_ops.mm +1559 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_search_ops.mm +568 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_shader_library.h +383 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_shader_library.mm +2350 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_slice_ops.mm +792 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_sparse_manip_ops.mm +836 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_sparse_ops.mm +396 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_sparse_segment_ops.mm +555 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_strided_ops.mm +639 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_training_ops.mm +489 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_transform_ops.mm +279 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/kernels/metal_volume_patch_ops.mm +245 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/metal_buffer_registry.h +103 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/metal_buffer_registry.mm +118 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/metal_platform.h +51 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/metal_platform.mm +205 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/metal_stream.h +269 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/metal_stream.mm +235 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/metal_stream_executor.h +40 -0
- tensorflow_metal_plugin-0.1.0/src/tensorflow/core/common_runtime/metal/metal_stream_executor.mm +693 -0
- tensorflow_metal_plugin-0.1.0/tensorflow-plugins/__init__.py +3 -0
- tensorflow_metal_plugin-0.1.0/tensorflow_metal_plugin.egg-info/PKG-INFO +273 -0
- tensorflow_metal_plugin-0.1.0/tensorflow_metal_plugin.egg-info/SOURCES.txt +91 -0
- tensorflow_metal_plugin-0.1.0/tensorflow_metal_plugin.egg-info/dependency_links.txt +1 -0
- tensorflow_metal_plugin-0.1.0/tensorflow_metal_plugin.egg-info/requires.txt +1 -0
- tensorflow_metal_plugin-0.1.0/tensorflow_metal_plugin.egg-info/top_level.txt +1 -0
- tensorflow_metal_plugin-0.1.0/tools/check_symbols.sh +29 -0
- tensorflow_metal_plugin-0.1.0/tools/compile_shaders.py +88 -0
- tensorflow_metal_plugin-0.1.0/tools/op_sweep.py +826 -0
- tensorflow_metal_plugin-0.1.0/tools/probe_stream_options.sh +17 -0
- tensorflow_metal_plugin-0.1.0/tools/recipes.py +958 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
|
202
|
+
|
|
203
|
+
## Some of TensorFlow's code is derived from Caffe, which is subject to the following copyright notice:
|
|
204
|
+
|
|
205
|
+
COPYRIGHT
|
|
206
|
+
|
|
207
|
+
All contributions by the University of California:
|
|
208
|
+
|
|
209
|
+
Copyright (c) 2014, The Regents of the University of California (Regents)
|
|
210
|
+
All rights reserved.
|
|
211
|
+
|
|
212
|
+
All other contributions:
|
|
213
|
+
|
|
214
|
+
Copyright (c) 2014, the respective contributors
|
|
215
|
+
All rights reserved.
|
|
216
|
+
|
|
217
|
+
Caffe uses a shared copyright model: each contributor holds copyright over
|
|
218
|
+
their contributions to Caffe. The project versioning records all such
|
|
219
|
+
contribution and copyright details. If a contributor wants to further mark
|
|
220
|
+
their specific copyright on a particular contribution, they should indicate
|
|
221
|
+
their copyright solely in the commit message of the change when it is
|
|
222
|
+
committed.
|
|
223
|
+
|
|
224
|
+
LICENSE
|
|
225
|
+
|
|
226
|
+
Redistribution and use in source and binary forms, with or without
|
|
227
|
+
modification, are permitted provided that the following conditions are met:
|
|
228
|
+
|
|
229
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
230
|
+
list of conditions and the following disclaimer.
|
|
231
|
+
|
|
232
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
233
|
+
this list of conditions and the following disclaimer in the documentation
|
|
234
|
+
and/or other materials provided with the distribution.
|
|
235
|
+
|
|
236
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
237
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
238
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
239
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
240
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
241
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
242
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
243
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
244
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
245
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
246
|
+
|
|
247
|
+
CONTRIBUTION AGREEMENT
|
|
248
|
+
|
|
249
|
+
By contributing to the BVLC/caffe repository through pull-request, comment,
|
|
250
|
+
or otherwise, the contributor releases their content to the
|
|
251
|
+
license and copyright terms herein.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# The wheel is built from source at install time, against whichever
|
|
2
|
+
# TensorFlow the installing interpreter has, so the sdist has to carry
|
|
3
|
+
# everything the build needs.
|
|
4
|
+
include Makefile
|
|
5
|
+
include LICENSE
|
|
6
|
+
include README.md
|
|
7
|
+
recursive-include src *.cc *.h *.mm
|
|
8
|
+
recursive-include tools *.sh *.py
|
|
9
|
+
recursive-include tensorflow-plugins *.py
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Builds the Metal PluggableDevice plugin against an installed TensorFlow.
|
|
2
|
+
#
|
|
3
|
+
# The header and library paths come from the TensorFlow package itself rather
|
|
4
|
+
# than from a checked-in copy, so the plugin is built against exactly the
|
|
5
|
+
# TensorFlow it will be loaded into.
|
|
6
|
+
|
|
7
|
+
# Whichever interpreter has the TensorFlow you intend to load the plugin into.
|
|
8
|
+
# Override it when `python3` on PATH is not that one:
|
|
9
|
+
# make PYTHON=/path/to/venv/bin/python
|
|
10
|
+
PYTHON ?= python3
|
|
11
|
+
TF_INCLUDE := $(shell $(PYTHON) -c "import tensorflow as tf; print(tf.sysconfig.get_include())")
|
|
12
|
+
TF_LIB := $(shell $(PYTHON) -c "import tensorflow as tf; print(tf.sysconfig.get_lib())")
|
|
13
|
+
SDK := $(shell xcrun --sdk macosx --show-sdk-path 2>/dev/null)
|
|
14
|
+
|
|
15
|
+
BUILD := build
|
|
16
|
+
OUT := $(BUILD)/libmetal_plugin.dylib
|
|
17
|
+
|
|
18
|
+
SOURCES := src/plugin_init.cc \
|
|
19
|
+
$(wildcard src/tensorflow/core/common_runtime/metal/*.mm) \
|
|
20
|
+
$(wildcard src/tensorflow/core/common_runtime/metal/kernels/*.mm)
|
|
21
|
+
OBJECTS := $(patsubst src/%,$(BUILD)/%.o,$(SOURCES))
|
|
22
|
+
|
|
23
|
+
# The sources use manual retain and release, matching how TensorFlow's own
|
|
24
|
+
# objc_library targets compile them. Turning ARC on here would reject them.
|
|
25
|
+
#
|
|
26
|
+
# STREAM_OPTIONS probes the installed headers for a StreamExecutor C API
|
|
27
|
+
# callback added after the last release, so one source tree serves both an
|
|
28
|
+
# in-tree build and a build against whatever TensorFlow is installed.
|
|
29
|
+
STREAM_OPTIONS := $(shell bash tools/probe_stream_options.sh $(TF_INCLUDE))
|
|
30
|
+
ifeq ($(STREAM_OPTIONS),no)
|
|
31
|
+
COMPAT := -DTF_METAL_NO_STREAM_OPTIONS
|
|
32
|
+
endif
|
|
33
|
+
|
|
34
|
+
# -MMD -MP writes a .d file per object listing the headers it included, so a
|
|
35
|
+
# change to a header rebuilds everything that reads it. Without this, adding a
|
|
36
|
+
# field to a struct recompiled only the file it was declared in and left the
|
|
37
|
+
# rest reading the old layout, which shows up as a stream reporting a failure
|
|
38
|
+
# that never happened.
|
|
39
|
+
CXXFLAGS := -std=c++17 -O2 -fPIC -isysroot $(SDK) $(COMPAT) -MMD -MP \
|
|
40
|
+
-mmacosx-version-min=13.0 \
|
|
41
|
+
-Isrc -I$(TF_INCLUDE) \
|
|
42
|
+
-I$(TF_INCLUDE)/external/farmhash_archive/src \
|
|
43
|
+
-DNDEBUG -DTF_METAL_OUT_OF_TREE \
|
|
44
|
+
-DTF_CAPI_WEAK
|
|
45
|
+
|
|
46
|
+
FRAMEWORKS := -framework Metal -framework MetalPerformanceShaders \
|
|
47
|
+
-framework MetalPerformanceShadersGraph -framework Foundation
|
|
48
|
+
|
|
49
|
+
# Linking against the framework library rather than deferring every symbol to
|
|
50
|
+
# load time: an undefined symbol should be a build failure here, not a crash
|
|
51
|
+
# in someone's first import.
|
|
52
|
+
# TF_CAPI_WEAK, which TensorFlow's own c_api_macros.h provides for exactly this
|
|
53
|
+
# case, makes every C API reference a weak one. Part of the kernel C API is
|
|
54
|
+
# declared in the headers a released TensorFlow ships without being exported by
|
|
55
|
+
# any binary in it, and dyld on macOS 13 and later binds at load rather than at
|
|
56
|
+
# first call, so an ordinary reference to one of those would make dlopen fail
|
|
57
|
+
# outright. Weak references bind to null instead, and the kernels that need
|
|
58
|
+
# them are not registered when they are null (see ResourceVariableApiAvailable).
|
|
59
|
+
LDFLAGS := -dynamiclib $(FRAMEWORKS) \
|
|
60
|
+
-L$(TF_LIB) -ltensorflow_framework.2 \
|
|
61
|
+
-Wl,-undefined,dynamic_lookup \
|
|
62
|
+
-Wl,-rpath,$(TF_LIB)
|
|
63
|
+
|
|
64
|
+
.PHONY: all clean test sweep install
|
|
65
|
+
|
|
66
|
+
all: $(OUT)
|
|
67
|
+
|
|
68
|
+
$(OUT): $(OBJECTS)
|
|
69
|
+
@mkdir -p $(dir $@)
|
|
70
|
+
$(CXX) $(OBJECTS) $(LDFLAGS) -o $@
|
|
71
|
+
@echo "built $@"
|
|
72
|
+
|
|
73
|
+
$(BUILD)/%.o: src/%
|
|
74
|
+
@mkdir -p $(dir $@)
|
|
75
|
+
$(CXX) $(CXXFLAGS) -c $< -o $@
|
|
76
|
+
|
|
77
|
+
# Fails loudly if the library still has unresolved TensorFlow or Metal symbols.
|
|
78
|
+
check-symbols: $(OUT)
|
|
79
|
+
@bash tools/check_symbols.sh $(OUT)
|
|
80
|
+
|
|
81
|
+
test: $(OUT)
|
|
82
|
+
$(PYTHON) tests/run_tests.py
|
|
83
|
+
|
|
84
|
+
# Every registered op, through TensorFlow's own dispatch, against the CPU.
|
|
85
|
+
sweep: $(OUT)
|
|
86
|
+
PYTHONPATH=tools $(PYTHON) tools/op_sweep.py
|
|
87
|
+
|
|
88
|
+
install: $(OUT)
|
|
89
|
+
$(PYTHON) -m pip install .
|
|
90
|
+
|
|
91
|
+
clean:
|
|
92
|
+
rm -rf $(BUILD)
|
|
93
|
+
|
|
94
|
+
-include $(OBJECTS:.o=.d)
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tensorflow-metal-plugin
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Metal GPU backend for TensorFlow on Apple silicon
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Classifier: Development Status :: 3 - Alpha
|
|
7
|
+
Classifier: Environment :: GPU
|
|
8
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
9
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: tensorflow>=2.16
|
|
15
|
+
Dynamic: classifier
|
|
16
|
+
Dynamic: description
|
|
17
|
+
Dynamic: description-content-type
|
|
18
|
+
Dynamic: license
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
Dynamic: requires-dist
|
|
21
|
+
Dynamic: requires-python
|
|
22
|
+
Dynamic: summary
|
|
23
|
+
|
|
24
|
+
# tensorflow-metal-plugin
|
|
25
|
+
|
|
26
|
+
A Metal GPU backend for TensorFlow on Apple silicon, built as an out-of-tree
|
|
27
|
+
PluggableDevice. It loads into a stock TensorFlow wheel and adds
|
|
28
|
+
`/physical_device:GPU:0`.
|
|
29
|
+
|
|
30
|
+
This is the out-of-tree form of the backend proposed in
|
|
31
|
+
[tensorflow/tensorflow#126254](https://github.com/tensorflow/tensorflow/pull/126254).
|
|
32
|
+
The sources are the same; the only difference is this repository exports
|
|
33
|
+
`SE_InitPlugin` and `TF_InitKernel` from a shared object, where the in-tree
|
|
34
|
+
form hands the same function pointers to `RegisterPluggableDevicePlugin`.
|
|
35
|
+
|
|
36
|
+
## Status
|
|
37
|
+
|
|
38
|
+
Working, and every op it registers has been run on a real GPU and checked.
|
|
39
|
+
One significant limitation is not this project's to fix: see
|
|
40
|
+
[What a released TensorFlow cannot do](#what-a-released-tensorflow-cannot-do).
|
|
41
|
+
|
|
42
|
+
`make sweep` calls all 356 registered ops through TensorFlow's own dispatch,
|
|
43
|
+
once on the GPU and once on the CPU with identical inputs, with soft placement
|
|
44
|
+
off so that a missing kernel raises rather than answering from the host:
|
|
45
|
+
|
|
46
|
+
| | |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| Verified against the CPU kernel, or against a property where there is no CPU kernel | 323 |
|
|
49
|
+
| Removed from TensorFlow, so no device can run them | 19 |
|
|
50
|
+
| Need kernel C API entry points a released TensorFlow does not export | 14 |
|
|
51
|
+
| **Unaccounted for** | **0** |
|
|
52
|
+
|
|
53
|
+
Every op is also run twice and required to give the same answer, which is how
|
|
54
|
+
an inverse transform that rewrote its own input was caught. The sweep
|
|
55
|
+
separately enumerates every registration TensorFlow holds for these ops and
|
|
56
|
+
rejects any that is duplicated or that constrains an attribute the op does not
|
|
57
|
+
have, since either makes an op unusable while looking registered.
|
|
58
|
+
|
|
59
|
+
Two of the nineteen announce themselves differently, complaining that a
|
|
60
|
+
kernel constrains an attribute the node lacks: TensorFlow's own CPU
|
|
61
|
+
registrations for `TopK` and `TileGrad` constrain `index_type` and
|
|
62
|
+
`Tmultiples`, which their op defs do not have. That is true and is not why
|
|
63
|
+
they cannot run. Both are deprecated in their op def, `TopK` from GraphDef
|
|
64
|
+
version 7 and `TileGrad` from version 3, so nothing can call them either way.
|
|
65
|
+
|
|
66
|
+
Verified on an Apple M4 Max, macOS 26.6, against the stock
|
|
67
|
+
`tensorflow==2.20.0` wheel for Python 3.12:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
before: ['/physical_device:CPU:0']
|
|
71
|
+
after : ['/physical_device:CPU:0', '/physical_device:GPU:0']
|
|
72
|
+
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`MatMul`, `Conv2D`, `Softmax`, `Relu`, `MaxPool2D` and `ReduceSum` match the
|
|
76
|
+
CPU kernels with soft placement disabled, so a missing GPU kernel raises
|
|
77
|
+
instead of quietly producing a correct answer on the wrong device.
|
|
78
|
+
|
|
79
|
+
## Install
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
pip install tensorflow
|
|
83
|
+
pip install git+https://github.com/IPNP-BIPN/tensorflow-metal-plugin
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
That is all. The shared object is built at install time against the
|
|
87
|
+
TensorFlow of the interpreter doing the installing, and lands in
|
|
88
|
+
`site-packages/tensorflow-plugins`, which TensorFlow scans at import. Nothing
|
|
89
|
+
has to be loaded by hand:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
>>> import tensorflow as tf
|
|
93
|
+
>>> tf.config.list_physical_devices()
|
|
94
|
+
[PhysicalDevice(name='/physical_device:CPU:0', device_type='CPU'),
|
|
95
|
+
PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Verified on a clean environment with `tensorflow==2.21.0`, Python 3.12, macOS
|
|
99
|
+
26.6 on an M4 Max.
|
|
100
|
+
|
|
101
|
+
## Training works, and what it costs today
|
|
102
|
+
|
|
103
|
+
`model.fit(optimizer="adam")` trains and the loss goes down. Getting there
|
|
104
|
+
needed a correction worth stating plainly, because it changes the speed.
|
|
105
|
+
|
|
106
|
+
TensorFlow's own kernels for resource variables reach a tensor through its
|
|
107
|
+
data pointer. On a unified memory device that pointer is host-addressable, so
|
|
108
|
+
those kernels read and write device memory from the host with no idea that GPU
|
|
109
|
+
work is in flight against it. A plugin is supposed to implement those ops
|
|
110
|
+
itself, through `tensorflow/c/kernels_experimental.h`, and order them on its
|
|
111
|
+
own stream. Since 2.20.0 no shipped binary defines those entry points
|
|
112
|
+
([#126374](https://github.com/tensorflow/tensorflow/issues/126374)), so the
|
|
113
|
+
ops fall back to the host and race.
|
|
114
|
+
|
|
115
|
+
The symptom was the worst kind: an optimiser read a slot variable mid-write,
|
|
116
|
+
took the square root of whatever was there, and produced `nan` weights with no
|
|
117
|
+
error raised. `model.fit` reported `[nan, nan, nan]` and carried on.
|
|
118
|
+
|
|
119
|
+
While those entry points are missing, every Metal kernel waits for the GPU
|
|
120
|
+
before returning, which closes the window. It is announced in a warning at
|
|
121
|
+
load, and `TF_METAL_SYNCHRONOUS` forces it either way. When the entry points
|
|
122
|
+
come back the plugin returns to running asynchronously with no change here.
|
|
123
|
+
|
|
124
|
+
## Is it faster than the CPU
|
|
125
|
+
|
|
126
|
+
Sometimes, and by how much depends entirely on the shape of the work. Measured
|
|
127
|
+
on an M4 Max against TensorFlow 2.21.0, median of ten runs each, both devices
|
|
128
|
+
in the same process on the same data, waiting for the device before stopping
|
|
129
|
+
the clock:
|
|
130
|
+
|
|
131
|
+
Two columns of speedup, because the wait above costs most of it. "Today" is
|
|
132
|
+
what you get from a released TensorFlow; "async" is the same machine with
|
|
133
|
+
`TF_METAL_SYNCHRONOUS=0`, which is what the plugin does once
|
|
134
|
+
[#126374](https://github.com/tensorflow/tensorflow/issues/126374) is fixed.
|
|
135
|
+
|
|
136
|
+
| | GPU today | CPU | today | async |
|
|
137
|
+
| --- | ---: | ---: | ---: | ---: |
|
|
138
|
+
| MatMul 2048x2048 | 3.80 ms | 14.42 ms | **3.8x** | 6.5x |
|
|
139
|
+
| Conv2D, batch 64, 64x64x32 to 64 | 4.58 ms | 10.91 ms | **2.4x** | 3.0x |
|
|
140
|
+
| MatMul 1024x1024 | 1.12 ms | 2.17 ms | 1.9x | 1.5x |
|
|
141
|
+
| CNN training step, SGD, batch 128 | 19.46 ms | 20.61 ms | 1.1x | 1.7x |
|
|
142
|
+
| CNN forward, batch 128 | 5.53 ms | 6.00 ms | 1.1x | 1.5x |
|
|
143
|
+
| MatMul 512x512 | 0.44 ms | 0.36 ms | 0.8x | 0.9x |
|
|
144
|
+
| ReduceSum 4096x4096 | 0.44 ms | 0.34 ms | 0.8x | 0.8x |
|
|
145
|
+
| Elementwise 4096x4096 | 2.88 ms | 1.54 ms | 0.5x | 0.5x |
|
|
146
|
+
|
|
147
|
+
The pattern is the ordinary one and worth stating plainly: the GPU wins where
|
|
148
|
+
there is arithmetic to do per byte moved, and loses where there is not. A
|
|
149
|
+
4096x4096 elementwise chain moves 67 MB and does three floating point
|
|
150
|
+
operations per element, so it is bound by memory on a machine whose CPU shares
|
|
151
|
+
that same memory. Small matrices lose to the cost of getting work to the
|
|
152
|
+
device at all.
|
|
153
|
+
|
|
154
|
+
A training step is 1.7x the CPU when the plugin can run asynchronously, and
|
|
155
|
+
barely ahead of it while it cannot. That gap is the cost of the missing entry
|
|
156
|
+
points, not of the backend.
|
|
157
|
+
|
|
158
|
+
`benchmarks/benchmark.py` reproduces the table.
|
|
159
|
+
|
|
160
|
+
## Build
|
|
161
|
+
|
|
162
|
+
Needs the macOS 15 SDK or later and a Python with TensorFlow installed. The
|
|
163
|
+
backend aliases an `MTLBuffer` through `MPSNDArray` with packed rows, and both
|
|
164
|
+
`initWithBuffer:offset:descriptor:` and `preferPackedRows` arrived in that SDK;
|
|
165
|
+
an older one does not declare them and the build stops rather than degrading. The
|
|
166
|
+
header and library paths come from that TensorFlow, so the plugin is built
|
|
167
|
+
against exactly the one it will be loaded into.
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
make # or: make PYTHON=/path/to/venv/bin/python
|
|
171
|
+
make check-symbols
|
|
172
|
+
make test
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Then either point TensorFlow at it directly:
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
from tensorflow.python.framework import load_library
|
|
179
|
+
load_library.load_pluggable_device_library("build/libmetal_plugin.dylib")
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
or install it so that `import tensorflow` finds it:
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
make install
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
`TF_DISABLE_METAL=1` keeps the backend out of the process without
|
|
189
|
+
uninstalling it.
|
|
190
|
+
|
|
191
|
+
## What a released TensorFlow cannot do
|
|
192
|
+
|
|
193
|
+
Six entry points of the kernel C API are declared in the headers a released
|
|
194
|
+
TensorFlow ships and are exported by no binary in it:
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
TF_AssignRefVariable
|
|
198
|
+
TF_AssignUpdateVariable
|
|
199
|
+
TF_GetInputTensorFromVariable
|
|
200
|
+
TF_MaybeLockVariableInputMutexesInOrder
|
|
201
|
+
TF_ReleaseVariableInputLockHolder
|
|
202
|
+
TF_OpKernelConstruction_GetAttrTensorShape
|
|
203
|
+
TF_OpKernelContext_ForwardRefInputToRefOutput
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Checked against `tensorflow==2.20.0` on macOS arm64: absent from
|
|
207
|
+
`libtensorflow_framework.2.dylib`, from `libtensorflow_cc.2.dylib`, and from
|
|
208
|
+
every pywrap module, and unresolvable by `dlsym` inside a live process.
|
|
209
|
+
`TF_AllocateOutput` and `TF_NewKernelBuilder`, from the same header set, are
|
|
210
|
+
exported normally, so this is not a matter of the whole C API being private.
|
|
211
|
+
|
|
212
|
+
Fifteen ops need them, and the plugin does not register those when the symbols
|
|
213
|
+
are missing, logging one warning instead:
|
|
214
|
+
|
|
215
|
+
| Family | Ops |
|
|
216
|
+
| --- | --- |
|
|
217
|
+
| Optimisers | `ResourceApplyAdam`, `ResourceApplyGradientDescent`, `ResourceApplyMomentum`, `ResourceApplyKerasMomentum`, `ResourceApplyRMSProp` |
|
|
218
|
+
| Resource gather and scatter | `ResourceGather`, `ResourceGatherNd`, `ResourceScatterUpdate`, `GatherNd` |
|
|
219
|
+
| Reference variables | `Assign`, `AssignAdd`, `AssignSub` |
|
|
220
|
+
| Parallel stacking | `ParallelConcat`, `_ParallelConcatStart`, `_ParallelConcatUpdate` |
|
|
221
|
+
|
|
222
|
+
The optimisers are the whole of that list that matters: **without them there is
|
|
223
|
+
no training on the GPU**, only inference and manual gradient work. They run on
|
|
224
|
+
the host instead, which is correct and slow.
|
|
225
|
+
|
|
226
|
+
This is a regression, not a standing limitation. All fourteen symbols of
|
|
227
|
+
`tensorflow/c/kernels_experimental.cc` are exported by `libtensorflow_framework`
|
|
228
|
+
in 2.19.1 and 2.18.1, and absent from every binary in the 2.20.0 wheel, with
|
|
229
|
+
none added in exchange. The headers still declare them. Filed upstream as
|
|
230
|
+
[tensorflow/tensorflow#126374](https://github.com/tensorflow/tensorflow/issues/126374).
|
|
231
|
+
|
|
232
|
+
So this is not something the plugin can work around, and it is not permanent
|
|
233
|
+
either: when those exports come back, the fifteen ops below start working here
|
|
234
|
+
with no change to this repository.
|
|
235
|
+
|
|
236
|
+
It is also the sharpest argument for the in-tree form, where the same code
|
|
237
|
+
links these functions directly and all fifteen ops work. That trade is the
|
|
238
|
+
subject of the discussion on
|
|
239
|
+
[#126254](https://github.com/tensorflow/tensorflow/pull/126254).
|
|
240
|
+
|
|
241
|
+
## Why this exists
|
|
242
|
+
|
|
243
|
+
Apple's `tensorflow-metal` last shipped 1.2.0 on 2025-01-31, publishes no
|
|
244
|
+
wheel past cp312, has no sdist, and its repository was archived in 2021. TF
|
|
245
|
+
master requires Python 3.10 or later and classifies up to cp313, so on a
|
|
246
|
+
current Python there is no GPU path for TensorFlow on a Mac at all.
|
|
247
|
+
|
|
248
|
+
## Op coverage
|
|
249
|
+
|
|
250
|
+
The backend registers every op TensorFlow registers for `DEVICE_GPU`, less the
|
|
251
|
+
five TensorRT ops that `if_tensorrt` excludes from a macOS build, and less the
|
|
252
|
+
fifteen above when the C API entry points they need are missing. The table of
|
|
253
|
+
Metal kernels with their dtypes is in
|
|
254
|
+
[docs/ops.md](docs/ops.md).
|
|
255
|
+
|
|
256
|
+
## Layout
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
src/plugin_init.cc the two exported entry points
|
|
260
|
+
src/tensorflow/core/common_runtime/metal/ the backend, verbatim from the
|
|
261
|
+
TensorFlow tree
|
|
262
|
+
tools/ build probes and the symbol check
|
|
263
|
+
tests/ on-device checks against CPU
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
The backend sources keep their TensorFlow paths so that syncing them from the
|
|
267
|
+
tree is a copy rather than a patch. Two macros, `TF_METAL_OUT_OF_TREE` and
|
|
268
|
+
`TF_METAL_NO_STREAM_OPTIONS`, are the whole of what the out-of-tree build
|
|
269
|
+
turns on; both are no-ops in the tree.
|
|
270
|
+
|
|
271
|
+
## Licence
|
|
272
|
+
|
|
273
|
+
Apache 2.0, the same as TensorFlow.
|