Um zu lernen, wie man benutzerdefinierte TensorFlow-Ops schreibt, folgte ich dem Hinzufügen eines neuen Ops tutorial und machte eine "add_b" -Operation, die jedem Eingabewert einen Skalar b
hinzufügt.
add_b_op.cc
:
add_b_op.cu.cc
Ich habe absichtlich einen Fehler in der CPU-Implementierung eingeführt, um unterscheiden zu können, ob die CPU- oder GPU-Implementierung verwendet wird.
Wenn ich meine benutzerdefinierte Funktion mit:
teste %Vor%Ich bekomme folgende Ausgabe:
%Vor%Die "Geräteplatzierungsprotokolle" scheinen anzuzeigen, dass die Operation auf der GPU ausgeführt wird, aber die Ausgabe zeigt an, dass die CPU-Implementierung verwendet wird.
Wenn ich die beiden REGISTER_KERNEL_BUILDER () Registrierungen für die DEVICE_CPU
Implementierung auskommentiere, neu kompiliere und erneut test, bekomme ich die erwartete Ausgabe von [ 13. 12. 11. 10. 9.]
, aber es gibt einen Fehler:
Diese Fehlermeldung sieht für mich wie ein Fehler aus, denn obwohl der Fehler besagt "Executor konnte den Kernel nicht erstellen", wurde anscheinend ein Kernel erstellt, um die Operation auf der GPU auszuführen.
Warum wird die CPU-Implementierung anstatt der GPU-Implementierung verwendet?
Falls dies wichtig ist, hier sind Details zu meiner Entwicklungsumgebung:
export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/gpu/tensorflow-0.11.0rc2-py2-none-any.whl
UPDATE Ich habe festgestellt, dass die Auswahl der CPU- oder GPU-Implementierung von der Größe der Eingabe abhängt. Mit diesem Testskript:
%Vor% .. Wenn NUM_VALUES
1310720 oder weniger ist, wird die CPU-Implementierung verwendet. Wenn NUM_VALUES
1310721 oder mehr ist, wird die GPU-Implementierung verwendet.
Gibt es eine (1310720 * 8 Bytes pro Doppel =) 10 MiB-Abschaltung? Wenn ja, wie überschreibe ich dies? Die Option AddB () ist einfach genug, aber für einen komplexeren benutzerdefinierten Vorgang könnten 10 MiB zu groß sein, als dass ein Schwellenwert für die GPU-Implementierung ausgewählt werden könnte.
Ich lese gerade TensorFlow-Problem # 2054 - Die manuelle Platzierung auf der GPU eines benutzerdefinierten Operators mit CPU- und GPU-Implementierung wird immer ausgeführt die CPU-Version und das Verhalten beim Ausführen der CPU-Implementierung scheint ein Merkmal von TensorFlow zu sein, das "Constant Folding" genannt wird. Wenn TensorFlow das Diagramm vor dem ersten Durchlauf optimiert, werden Operationen mit Konstanten in der Regel auf der CPU ausgewertet, da CPU- und GPU-Implementierungen die gleichen Ergebnisse liefern sollen. Macht Sinn.
Zwei Möglichkeiten zum Deaktivieren dieses Verhaltens sind:
Deaktivieren der Grafikoptimierung:
%Vor%Verwenden Sie keine Konstanten, indem Sie beispielsweise die Werte in Platzhalter einspeisen:
%Vor%Ich denke, die Template-Instanziierungen könnten falsch sein:
%Vor%Und dann:
%Vor%Ich denke, die Registrierung von AddB für GPU instanziiert das Objekt, das der ersten Implementierung entspricht, nicht die zweite (die erste Implementierung hat zwei Vorlagenargumente, die zweite Implementierung hat eine).
Sie könnten das wahrscheinlich beheben, indem Sie AddBOp & lt; float & gt; in der zweiten Registrierung, obwohl ich bessere Namen empfehlen würde, um Verwirrung zu vermeiden.
Nach diesem kann es aufgrund von Speicherfragmentierung Management sein, versuchen Sie es :
%Vor%Oder die Snippets auf der verknüpften Seite für die Optimierung der Speicherfragmentierungsoptionen.
BEARBEITEN: Um zu sehen, ob das der Fall ist, versuchen Sie:
%Vor%Tags und Links c++ tensorflow custom-operator