1c8b59c046895fa5b6d79f73e0b5817330fcfbfc1A. Unique TensorFlower/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
29c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur
39c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurLicensed under the Apache License, Version 2.0 (the "License");
49c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudluryou may not use this file except in compliance with the License.
59c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurYou may obtain a copy of the License at
69c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur
79c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur    http://www.apache.org/licenses/LICENSE-2.0
89c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur
99c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurUnless required by applicable law or agreed to in writing, software
109c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlurdistributed under the License is distributed on an "AS IS" BASIS,
119c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurSee the License for the specific language governing permissions and
139c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlurlimitations under the License.
149c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur==============================================================================*/
159c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur
16f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#ifndef TENSORFLOW_PLATFORM_TRACING_H_
17f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#define TENSORFLOW_PLATFORM_TRACING_H_
18f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
19f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// Tracing interface
20f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
21f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan#include <atomic>
22f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include <map>
23f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include <memory>
24f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
25f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/core/lib/core/stringpiece.h"
26f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan#include "tensorflow/core/lib/strings/strcat.h"
27252bb90ca2dd412ca2fd2908faf1a25d6ef618cfJosh Levenberg#include "tensorflow/core/platform/macros.h"
28ded61708dbc7f5615119a3623c8fe7f112882e0fJosh Levenberg#include "tensorflow/core/platform/mutex.h"
29c8eaac926c929e07ac8db69f67803a2223ff2d93Josh Levenberg#include "tensorflow/core/platform/platform.h"
30ded61708dbc7f5615119a3623c8fe7f112882e0fJosh Levenberg#include "tensorflow/core/platform/types.h"
31f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
32f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurnamespace tensorflow {
33f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
34f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurnamespace port {
35f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
36f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurclass Tracing {
37f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur public:
38f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // This enumeration contains the identifiers of all TensorFlow
39f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // threadscape events and code regions.  Threadscape assigns its
409b70316263eb74476ab96b7c0f300c4d90223425Vijay Vasudevan  // own identifiers at runtime when we register our events and we
41f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // cannot know in advance what IDs it will choose.  The "RecordEvent"
42f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // method and "ScopedActivity" use these event IDs for consistency
43f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // and remap them to threadscape IDs at runtime.  This enum is limited
44f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // to 64 values since we use a bitmask to configure which events are
45f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // enabled.  It must also be kept in step with the code in
46f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // "Tracing::EventCategoryString".
47f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  enum EventCategory {
48f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    kScheduleClosure = 0,
49f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    kRunClosure = 1,
50f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    kCompute = 2,
51f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    kEventCategoryMax = 3  // sentinel - keep last
52f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  };
53f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Note: We currently only support up to 64 categories.
54f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  static_assert(kEventCategoryMax <= 64, "only support up to 64 events");
55f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
56f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Called by main programs to initialize tracing facilities
57f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  static void Initialize();
58f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
59f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Return the pathname of the directory where we are writing log files.
60f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  static const char* LogDir();
61f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
62f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Returns a non-zero identifier which can be used to correlate
63f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // related events.
64f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  static inline uint64 UniqueId();
65f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
66f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Returns true if a trace is in progress.  Can be used to reduce tracing
67f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // overheads in fast-path code.
68f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  static inline bool IsActive();
69f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
70f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Associate name with the current thread.
71f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  static void RegisterCurrentThread(const char* name);
72f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
73f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Posts an event with the supplied category and arg.
74f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  static void RecordEvent(EventCategory category, uint64 arg);
75f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
76f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Traces a region of code.  Posts a tracing "EnterCodeRegion" event
77f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // when created and an "ExitCodeRegion" event when destroyed.
78f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  class ScopedActivity {
79f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur   public:
80f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    explicit ScopedActivity(EventCategory category, uint64 arg);
81f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    ~ScopedActivity();
82f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
83f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur   private:
849917b53a41345cf30954a5a4b17985412f1acfdeJosh Levenberg#if defined(PLATFORM_GOOGLE)
85f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    const bool enabled_;
86f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    const int32 region_id_;
879917b53a41345cf30954a5a4b17985412f1acfdeJosh Levenberg#endif
88f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
89f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    TF_DISALLOW_COPY_AND_ASSIGN(ScopedActivity);
90f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  };
91f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
92f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Trace collection engine can be registered with this module.
93f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // If no engine is registered, ScopedAnnotation and TraceMe are no-ops.
94f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  class Engine;
95f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  static void RegisterEngine(Engine*);
96f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
97f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Forward declaration of the GPU utility classes.
98f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  class ScopedAnnotation;
99f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  class TraceMe;
100f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
101f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur private:
102f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  friend class TracingTest;
103f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  friend class ScopedAnnotation;
104f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  friend class TraceMe;
105f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan
106f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  static std::atomic<Tracing::Engine*> tracing_engine_;
107f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  static Tracing::Engine* engine() {
108f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan    return tracing_engine_.load(std::memory_order_acquire);
109f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  }
110f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
111f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  static void RegisterEvent(EventCategory id, const char* name);
112f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  static const char* EventCategoryString(EventCategory category);
113f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
114f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  //
115f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Parses event mask expressions in 'value' of the form:
116f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  //   expr ::= <term> (,<term>)*
117f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  //   term ::= <event> | "!" <event>
118f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  //   event ::= "ALL" | <wait_event> | <other_event>
119f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  //   wait_event ::= "ENewSession" | "ECloseSession" | ...
120f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  //   other_event ::= "Send" | "Wait" | ...
121f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // ALL denotes all events, <event> turns on tracing for this event, and
122f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // !<event> turns off tracing for this event.
123f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // If the expression can be parsed correctly it returns true and sets
124f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // the event_mask_. Otherwise it returns false and the event_mask_ is left
125f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // unchanged.
126f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  static bool ParseEventMask(const char* flagname, const string& value);
127f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
128f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Bit mask of enabled trace categories.
129f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  static uint64 event_mask_;
130f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
131f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Records the mappings between Threadscape IDs and the "EventCategory" enum.
132f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  static int32 category_id_[kEventCategoryMax];
133f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  static std::map<string, int32>* name_map_;
134f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur};
135f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
136f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// Trace collection engine that actually implements collection.
137f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurclass Tracing::Engine {
138f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur public:
139f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  Engine() {}
140f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  virtual ~Engine();
141f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
1421c579361cd1e088dd5e05a394b1561a73e3667baA. Unique TensorFlower  // Returns true if Tracing is currently enabled.
1431c579361cd1e088dd5e05a394b1561a73e3667baA. Unique TensorFlower  virtual bool IsEnabled() const = 0;
1441c579361cd1e088dd5e05a394b1561a73e3667baA. Unique TensorFlower
145f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Represents an active annotation.
146f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  class Annotation {
147f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur   public:
148f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    Annotation() {}
149f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    virtual ~Annotation();
150f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  };
151f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
152f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Represents an active trace.
153f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  class Tracer {
154f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur   public:
155f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    Tracer() {}
156f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    virtual ~Tracer();
157f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  };
158f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
159f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur private:
160f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  friend class ScopedAnnotation;
161f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  friend class TraceMe;
162f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
163f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Register the specified name as an annotation on the current thread.
164f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Caller should delete the result to remove the annotation.
165f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Annotations from the same thread are destroyed in a LIFO manner.
166f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // May return nullptr if annotations are not supported.
167f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  virtual Annotation* PushAnnotation(StringPiece name) = 0;
168f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
1691d230767f46967201b0c792931bfe81ed2675ee1A. Unique TensorFlower  // Start tracing under the specified label. Caller should delete the result
1701d230767f46967201b0c792931bfe81ed2675ee1A. Unique TensorFlower  // to stop tracing.
171f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // May return nullptr if tracing is not supported.
172ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlower  virtual Tracer* StartTracing(StringPiece label, bool is_expensive) = 0;
1731d230767f46967201b0c792931bfe81ed2675ee1A. Unique TensorFlower  // Same as above, but implementations can avoid copying the string.
174ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlower  virtual Tracer* StartTracing(string&& label, bool is_expensive) {
175ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlower    return StartTracing(StringPiece(label), is_expensive);
1761d230767f46967201b0c792931bfe81ed2675ee1A. Unique TensorFlower  }
177d6a9cd40c1987e2caf9cd2956e398a68881f4b5dA. Unique TensorFlower
178d6a9cd40c1987e2caf9cd2956e398a68881f4b5dA. Unique TensorFlower  // Backwards compatibility one arg variants (assume is_expensive=true).
179d6a9cd40c1987e2caf9cd2956e398a68881f4b5dA. Unique TensorFlower  Tracer* StartTracing(StringPiece label) {
180d6a9cd40c1987e2caf9cd2956e398a68881f4b5dA. Unique TensorFlower    return StartTracing(label, /*is_expensive=*/true);
181d6a9cd40c1987e2caf9cd2956e398a68881f4b5dA. Unique TensorFlower  }
182d6a9cd40c1987e2caf9cd2956e398a68881f4b5dA. Unique TensorFlower  Tracer* StartTracing(string&& label) {
183d6a9cd40c1987e2caf9cd2956e398a68881f4b5dA. Unique TensorFlower    return StartTracing(StringPiece(label), /*is_expensive=*/true);
184d6a9cd40c1987e2caf9cd2956e398a68881f4b5dA. Unique TensorFlower  }
185f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur};
186f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
187f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// This class permits a user to apply annotation on kernels and memcpys
188f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// when launching them. While an annotation is in scope, all activities
189f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// within that scope get their names replaced by the annotation. The kernel
190f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// name replacement is done when constructing the protobuf for sending out to
191f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// a client (e.g., the stubby requestor) for both API and Activity records.
192f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur//
193f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// Ownership: The creator of ScopedAnnotation assumes ownership of the object.
194f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur//
195f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// Usage: {
196f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur//          ScopedAnnotation annotation("first set of kernels");
197f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur//          Kernel1<<<x,y>>>;
198f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur//          LaunchKernel2(); // Which eventually launches a cuda kernel.
199f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur//        }
200f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// In the above scenario, the GPUProf UI would show 2 kernels with the name
201f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// "first set of kernels" executing -- they will appear as the same kernel.
202f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurclass Tracing::ScopedAnnotation {
203f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur public:
204f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  explicit ScopedAnnotation(StringPiece name);
205f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
206f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  // If tracing is enabled, set up an annotation with a label of
207f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  // "<name_part1>:<name_part2>".  Can be cheaper than the
208f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  // single-argument constructor because the concatenation of the
209f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  // label string is only done if tracing is enabled.
210f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  ScopedAnnotation(StringPiece name_part1, StringPiece name_part2);
211f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan
21255d1978d73ece0f72347f27bba134b5975f4d0c8Jeffrey A. Dean  // Returns true iff scoped annotations are active.
21355d1978d73ece0f72347f27bba134b5975f4d0c8Jeffrey A. Dean  static bool Enabled() {
21455d1978d73ece0f72347f27bba134b5975f4d0c8Jeffrey A. Dean    auto e = Tracing::engine();
21555d1978d73ece0f72347f27bba134b5975f4d0c8Jeffrey A. Dean    return e && e->IsEnabled();
21655d1978d73ece0f72347f27bba134b5975f4d0c8Jeffrey A. Dean  }
21755d1978d73ece0f72347f27bba134b5975f4d0c8Jeffrey A. Dean
218f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur private:
219f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  std::unique_ptr<Engine::Annotation> annotation_;
220f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur};
221f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
222f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// TODO(opensource): clean up the scoped classes for GPU tracing.
223f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// This class permits user-specified (CPU) tracing activities. A trace
224f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// activity is started when an object of this class is created and stopped
225f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// when the object is destroyed.
226f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurclass Tracing::TraceMe {
227f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur public:
228f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  explicit TraceMe(StringPiece name);
229ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlower  TraceMe(StringPiece name, bool is_expensive);
230f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
231d146e67e20f1288cf7ea4441eb3c3301cf7fad43A. Unique TensorFlower  // If tracing is enabled, set up a traceMe with a label of
232d146e67e20f1288cf7ea4441eb3c3301cf7fad43A. Unique TensorFlower  // "<name_part1>:<name_part2>".  This can be cheaper than the
233d146e67e20f1288cf7ea4441eb3c3301cf7fad43A. Unique TensorFlower  // single-argument constructor because the concatenation of the
234d146e67e20f1288cf7ea4441eb3c3301cf7fad43A. Unique TensorFlower  // label string is only done if tracing is enabled.
235d146e67e20f1288cf7ea4441eb3c3301cf7fad43A. Unique TensorFlower  TraceMe(StringPiece name_part1, StringPiece name_part2);
236ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlower  TraceMe(StringPiece name_part1, StringPiece name_part2, bool is_expensive);
237d146e67e20f1288cf7ea4441eb3c3301cf7fad43A. Unique TensorFlower
238f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur private:
239f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  std::unique_ptr<Engine::Tracer> tracer_;
240f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur};
241f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
242f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevaninline Tracing::ScopedAnnotation::ScopedAnnotation(StringPiece name) {
243f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  auto e = Tracing::engine();
2441c579361cd1e088dd5e05a394b1561a73e3667baA. Unique TensorFlower  if (e && e->IsEnabled()) {
245f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan    annotation_.reset(e->PushAnnotation(name));
246f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  }
247f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan}
248f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan
249f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevaninline Tracing::ScopedAnnotation::ScopedAnnotation(StringPiece name_part1,
250f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan                                                   StringPiece name_part2) {
251f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  auto e = Tracing::engine();
2521c579361cd1e088dd5e05a394b1561a73e3667baA. Unique TensorFlower  if (e && e->IsEnabled()) {
253f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan    annotation_.reset(
254f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan        e->PushAnnotation(strings::StrCat(name_part1, ":", name_part2)));
255f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  }
256f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan}
257f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan
258ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlowerinline Tracing::TraceMe::TraceMe(StringPiece name) : TraceMe(name, true) {}
259ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlower
260ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlowerinline Tracing::TraceMe::TraceMe(StringPiece name, bool is_expensive) {
261f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  auto e = Tracing::engine();
2621c579361cd1e088dd5e05a394b1561a73e3667baA. Unique TensorFlower  if (e && e->IsEnabled()) {
263ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlower    tracer_.reset(e->StartTracing(name, is_expensive));
264f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan  }
265f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan}
266f9d3e9d03c69bfac77a2fe1ad80f7c5aa517e0f0Vijay Vasudevan
267ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlowerinline Tracing::TraceMe::TraceMe(StringPiece name_part1, StringPiece name_part2)
268ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlower    : TraceMe(name_part1, name_part2, true) {}
269ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlower
270ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlowerinline Tracing::TraceMe::TraceMe(StringPiece name_part1, StringPiece name_part2,
271ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlower                                 bool is_expensive) {
272d146e67e20f1288cf7ea4441eb3c3301cf7fad43A. Unique TensorFlower  auto e = Tracing::engine();
273d146e67e20f1288cf7ea4441eb3c3301cf7fad43A. Unique TensorFlower  if (e && e->IsEnabled()) {
274ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlower    tracer_.reset(e->StartTracing(strings::StrCat(name_part1, ":", name_part2),
275ba5a5bfc23065086990ec3057caa2ded0c8a8dbfA. Unique TensorFlower                                  is_expensive));
276d146e67e20f1288cf7ea4441eb3c3301cf7fad43A. Unique TensorFlower  }
277d146e67e20f1288cf7ea4441eb3c3301cf7fad43A. Unique TensorFlower}
278d146e67e20f1288cf7ea4441eb3c3301cf7fad43A. Unique TensorFlower
279f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}  // namespace port
280f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}  // namespace tensorflow
281f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
282f2102f4e2c1c87f1d1bf9ab856a2849c54478760Vijay Vasudevan#if defined(PLATFORM_GOOGLE)
283f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/core/platform/google/tracing_impl.h"
284f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#else
285f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/core/platform/default/tracing_impl.h"
286f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#endif
287f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
288f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#endif  // TENSORFLOW_PLATFORM_TRACING_H_
289