text:
class guiCanvas;
typedef Signal<void(GuiCanvas* canvas)> CanvasSizeChangeSignal;
class GuiCanvas : public GuiControl, public IProcessInput
{

protected:
   typedef GuiControl Parent;

   /// @name Rendering
   /// @{
   RectI      mOldUpdateRects[2];
   RectI      mCurUpdateRect;
   U32        mLastRenderMs;
   /// @}

   /// @name Cursor Properties
   /// @{

   bool        mCursorEnabled;
   bool        mShowCursor;
   bool        mRenderFront;
   Point2F     mCursorPt;                             ///< Current cursor position in local coordinates.
   Point2I     mLastCursorPt;
   GuiCursor   *mDefaultCursor;
   GuiCursor   *mLastCursor;
   bool        mLastCursorEnabled;
   bool        mForceMouseToGUI;
   bool        mClampTorqueCursor;
   bool        mAlwaysHandleMouseButtons;

   bool        mDisplayWindow;

   /// @}

   /// @name Mouse Input
   /// @{

   SimObjectPtr<GuiControl>   mMouseCapturedControl;  ///< All mouse events will go to this ctrl only
   SimObjectPtr<GuiControl>   mMouseControl;          ///< the control the mouse was last seen in unless some other one captured it
   bool                       mMouseControlClicked;   ///< whether the current ctrl has been clicked - used by helpctrl
   U32                        mPrevMouseTime;         ///< this determines how long the mouse has been in the same control
   bool                       mMouseButtonDown;       ///< Flag to determine if the button is depressed
   bool                       mMouseRightButtonDown;  ///< bool to determine if the right button is depressed
   bool                       mMouseMiddleButtonDown; ///< Middle button flag
   GuiEvent                   mLastEvent;

   U8                         mLastMouseClickCount;
   S32                        mLastMouseDownTime;
   bool                       mLeftMouseLast;
   bool                       mMiddleMouseLast;
   bool                       mRightMouseLast;
   Point2F                    mMouseDownPoint;

   /// Processes keyboard input events. Helper method for processInputEvent
   ///
   /// \param inputEvent Information on the input even to be processed.
   /// \return True if the event was handled or false if it was not.
   virtual bool processKeyboardEvent(InputEventInfo &inputEvent);

   /// Processes mouse input events. Helper method for processInputEvent
   ///
   /// \param inputEvent Information on the input even to be processed.
   /// \return True if the event was handled or false if it was not.
   virtual bool processMouseEvent(InputEventInfo &inputEvent);

   /// Processes gamepad input events. Helper method for processInputEvent
   ///
   /// \param inputEvent Information on the input even to be processed.
   /// \return True if the event was handled or false if it was not.
   virtual bool processGamepadEvent(InputEventInfo &inputEvent);

   virtual void findMouseControl(const GuiEvent &event);
   virtual void refreshMouseControl();
   /// @}

   /// @name Keyboard Input
   /// @{

   /// Accelerator key map
   struct AccKeyMap
   {
      GuiControl *ctrl;
      U32 index;
      U32 keyCode;
      U32 modifier;
   };
   Vector <AccKeyMap> mAcceleratorMap;

   //for tooltip rendering
   U32            mHoverControlStart;
   GuiControl*    mHoverControl;
   Point2I        mHoverPosition;
   bool           mHoverPositionSet;
   U32            mHoverLeftControlTime;

   /// @}

   // Internal event handling callbacks for use with PlatformWindow.
   void handleResize     (WindowId did, S32 width,     S32 height);
   void handleAppEvent   (WindowId did, S32 event);
   void handlePaintEvent (WindowId did);

   PlatformWindow *mPlatformWindow;
   GFXFence **mFences;
   S32 mNextFenceIdx;
   S32 mNumFences;

   static bool setProtectedNumFences( void *object, const char *index, const char *data );
   virtual void setupFences();

   void checkLockMouseMove( const GuiEvent& event );
   //Signal used to let others know this canvas has changed size.
	static CanvasSizeChangeSignal smCanvasSizeChangeSignal;

   GuiControl *mMenuBarCtrl;

public:
   DECLARE_CONOBJECT(GuiCanvas);
   DECLARE_CATEGORY( "Gui Core" );

   GuiCanvas();
   virtual ~GuiCanvas();

   virtual bool onAdd();
   virtual void onRemove();

   void setMenuBar(SimObject *obj);

   static void initPersistFields();

   static CanvasSizeChangeSignal& getCanvasSizeChangeSignal() { return smCanvasSizeChangeSignal; }

   /// @name Rendering methods
   ///
   /// @{

   /// Repaints the dirty regions of the canvas
   /// @param   preRenderOnly   If set to true, only the onPreRender methods of all the GuiControls will be called
   /// @param   bufferSwap      If set to true, it will swap buffers at the end. This is to support canvas-subclassing.
   virtual void renderFrame(bool preRenderOnly, bool bufferSwap = true);

   /// Repaints the canvas by calling the platform window display event.
   virtual void paint();

   /// Repaints the canvas skipping rendering if the target time
   /// has not yet elapsed.
   /// @param  elapsedMS The time since the last frame.
   virtual void repaint(U32 elapsedMS);

   /// This signal is triggered at the beginning and end of each render frame
   ///
   /// @param beginFrame true at the beginning of the frame, false at the end
   ///
   typedef Signal <void ( bool beginFrame )> GuiCanvasFrameSignal;

   static GuiCanvasFrameSignal& getGuiCanvasFrameSignal();

   /// Adds a dirty area to the canvas so it will be updated on the next frame
   /// @param   pos   Screen-coordinates of the upper-left hand corner of the dirty area
   /// @param   ext   Width/height of the dirty area
   virtual void addUpdateRegion(Point2I pos, Point2I ext);

   /// Resets the update regions so that the next call to renderFrame will
   /// repaint the whole canvas
   virtual void resetUpdateRegions();

   /// Resizes the content control to match the canvas size.
   void maintainSizing();

   /// This builds a rectangle which encompasses all of the dirty regions to be
   /// repainted
   /// @param   updateUnion   (out) Rectangle which surrounds all dirty areas
   virtual void buildUpdateUnion(RectI *updateUnion);

   /// This will swap the buffers at the end of renderFrame. It was added for canvas
   /// sub-classes in case they wanted to do some custom code before the buffer
   /// flip occured.
   virtual void swapBuffers();

   /// @}

   /// @name Canvas Content Management
   /// @{

   /// This returns the PlatformWindow owned by this Canvas
   virtual PlatformWindow *getPlatformWindow()
   {
      return mPlatformWindow;
   }

   /// This sets the content control to something different
   /// @param   gui   New content control
   virtual void setContentControl(GuiControl *gui);

   /// Returns the content control
   virtual GuiControl *getContentControl();

   /// Adds a dialog control onto the stack of dialogs
   /// @param   gui   Dialog to add
   /// @param   layer   Layer to put dialog on
   /// @param   center  Center dialog on canvas.
   virtual void pushDialogControl(GuiControl *gui, S32 layer = 0, bool center = false);

   /// Removes a specific layer of dialogs
   /// @param   layer   Layer to pop off from
   virtual void popDialogControl(S32 layer = 0);

   /// Removes a specific dialog control
   /// @param   gui   Dialog to remove from the dialog stack
   virtual void popDialogControl(GuiControl *gui);
   ///@}

   /// This turns on/off front-buffer rendering
   /// @param   front   True if all rendering should be done to the front buffer
   virtual void setRenderFront(bool front) { mRenderFront = front; }

   /// @name Cursor commands
   /// A cursor can be on, but not be shown. If a cursor is not on, than it does not
   /// process input.
   /// @{

   /// Sets the cursor for the canvas.
   /// @param   cursor   New cursor to use.
   virtual void setCursor(GuiCursor *cursor);
   S32 mCursorChanged;

   /// Returns true if the cursor is on.
   virtual bool isCursorON() { return mCursorEnabled; }

   /// Sets if mouse events should be passed to the GUI even if the cursor is off.
   /// @param   onOff   True if events should be passed to the GUI if the cursor is off
   virtual void setForceMouseToGUI(bool onOff);

   /// Sets if the Torque cursor should be clamped to the window.
   /// @param  onOff    True if the Torque cursor should be clamped against the window
   virtual void setClampTorqueCursor(bool onOff);

   /// Returns if the Torque cursor is clamped to the window
   virtual bool getClampTorqueCursor() { return mClampTorqueCursor; }

   /// Turns the cursor on or off.
   /// @param   onOff   True if the cursor should be on.
   virtual void setCursorON(bool onOff);

   /// Sets the position of the cursor
   /// @param   pt   Point, in screenspace for the cursor
   virtual void setCursorPos(const Point2I &pt);

   /// Returns the point, in screenspace, at which the cursor is located.
   virtual Point2I getCursorPos();

   /// Enable/disable rendering of the cursor.
   /// @param   state    True if we should render cursor
   virtual void showCursor(bool state);

   /// Returns true if the cursor is being rendered.
   virtual bool isCursorShown();

   void cursorClick(S32 buttonId, bool isDown);

   void cursorNudge(F32 x, F32 y);
   /// @}

   ///used by the tooltip resource
   Point2I getCursorExtent() { return mDefaultCursor->getExtent(); }

   /// @name Input Processing
   /// @{

   /// Processes an input event
   /// @see InputEvent
   /// @param   event   Input event to process
   virtual bool processInputEvent(InputEventInfo &inputEvent);
   /// @}

   /// @name Mouse Methods
   /// @{

   /// When a control gets the mouse lock this means that that control gets
   /// ALL mouse input and no other control receives any input.
   /// @param   lockingControl   Control to lock mouse to
   virtual void mouseLock(GuiControl *lockingControl);

   /// Unlocks the mouse from a control
   /// @param   lockingControl   Control to unlock from
   virtual void mouseUnlock(GuiControl *lockingControl);

   /// Returns the control which the mouse is over
   virtual GuiControl* getMouseControl()       { return mMouseControl; }

   /// Returns the control which the mouse is locked to if any
   virtual GuiControl* getMouseLockedControl() { return mMouseCapturedControl; }

   /// Returns true if the left mouse button is down
   virtual bool mouseButtonDown(void) { return mMouseButtonDown; }

   /// Returns true if the right mouse button is down
   virtual bool mouseRightButtonDown(void) { return mMouseRightButtonDown; }

   /// @}

   /// @name Mouse input methods
   /// These events process the events before passing them down to the
   /// controls they effect. This allows for things such as the input
   /// locking and such.
   ///
   /// Each of these methods corresponds to the action in it's method name
   /// and processes the GuiEvent passed as a parameter
   /// @{
   virtual void rootMouseUp(const GuiEvent &event);
   virtual void rootMouseDown(const GuiEvent &event);
   virtual void rootMouseMove(const GuiEvent &event);
   virtual void rootMouseDragged(const GuiEvent &event);

   virtual void rootRightMouseDown(const GuiEvent &event);
   virtual void rootRightMouseUp(const GuiEvent &event);
   virtual void rootRightMouseDragged(const GuiEvent &event);

   virtual void rootMiddleMouseDown(const GuiEvent &event);
   virtual void rootMiddleMouseUp(const GuiEvent &event);
   virtual void rootMiddleMouseDragged(const GuiEvent &event);

   virtual bool rootMouseWheelUp(const GuiEvent &event);
   virtual bool rootMouseWheelDown(const GuiEvent &event);
   /// @}

   /// @name Keyboard input methods
   /// First responders
   ///
   /// A first responder is a the GuiControl which responds first to input events
   /// before passing them off for further processing.
   /// @{

   /// Moves the first responder to the next tabable controle
   virtual bool tabNext(void);

   /// Moves the first responder to the previous tabable control
   virtual bool tabPrev(void);

   /// Setups a keyboard accelerator which maps to a GuiControl.
   ///
   /// @param   ctrl       GuiControl to map to.
   /// @param   index
   /// @param   keyCode    Key code.
   /// @param   modifier   Shift, ctrl, etc.
   virtual void addAcceleratorKey(GuiControl *ctrl, U32 index, U32 keyCode, U32 modifier);

   /// Sets the first responder.
   /// @param   firstResponder    Control to designate as first responder
   virtual void setFirstResponder(GuiControl *firstResponder);

   /// This is used to toggle processing of native OS accelerators, not
   /// to be confused with the Torque accelerator key system, to keep them
   /// from swallowing up keystrokes.  Both GuiTextEditCtrl and GuiTextPadCtrl
   /// use this method.
   virtual void setNativeAcceleratorsEnabled( bool enabled );
   /// @}

   ///
   virtual Point2I getWindowSize();

   virtual void enableKeyboardTranslation();
   virtual void disableKeyboardTranslation();

   virtual void setWindowTitle(const char *newTitle);

private:
   static const U32 MAX_GAMEPADS = 4; ///< The maximum number of supported gamepads
};

#endif


text:
export const environment = {
  production: false,
  firebase: {
    apiKey: "AIzaSyCkUNfoL-zdi9xHz7Rz_l98LGgAx1_5a50",
    authDomain: "realtime-598ea.firebaseapp.com",
    databaseURL: "https://realtime-598ea.firebaseio.com",
    projectId: "realtime-598ea",
    storageBucket: "realtime-598ea.appspot.com",
    messagingSenderId: "668427691584"
  }
};

redpajama_set_name: RedPajamaGithub


text:
module.exports = {
  debug: false,
  basePath: '/',
  jsonPath: '/swagger.json',
  documentationPath: '/documentation',
  swaggerUIPath: '/swaggerui/',
  auth: false,
  pathPrefixSize: 1,
  payloadType: 'json',
  documentationPage: true,
  swaggerUI: true,
  jsonEditor: false,
  expanded: 'list',   // none, list or full
  lang: 'en',
  sortTags: 'default',
  sortEndpoints: 'path',
  sortPaths: 'unsorted',
  uiCompleteScript: null,
  xProperties: true,
  reuseModels: true,
  deReference: false,
  validatorUrl: '//online.swagger.io/validator',
  acceptToProduce: true,  // internal, NOT public
  connectionLabel: null,
  pathReplacements: [],
  tags: [],
  validateResponse: false
}


text:
<!DOCTYPE html>

    <meta http-equiv="refresh" content="0;URL=../../libc/constant.POLLIN.html">

Redirecting to ../../libc/constant.POLLIN.html...


text:
// HLO instructions are in DAG form and represent the computations that the user
// has built up via the XLA service interface. They are ultimately lowered
// in a platform-aware way by traversing the HLO DAG and emitting a lowered
// form; e.g. see DfsHloVisitor.

#ifndef TENSORFLOW_COMPILER_XLA_SERVICE_HLO_INSTRUCTION_H_
#define TENSORFLOW_COMPILER_XLA_SERVICE_HLO_INSTRUCTION_H_

#include <functional>
#include <iosfwd>
#include <list>
#include <memory>
#include <set>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "tensorflow/compiler/xla/iterator_util.h"
#include "tensorflow/compiler/xla/literal_util.h"
#include "tensorflow/compiler/xla/map_util.h"
#include "tensorflow/compiler/xla/service/dfs_hlo_visitor.h"
#include "tensorflow/compiler/xla/service/hlo.pb.h"
#include "tensorflow/compiler/xla/service/hlo_clone_context.h"
#include "tensorflow/compiler/xla/service/hlo_domain_metadata.h"
#include "tensorflow/compiler/xla/service/hlo_opcode.h"
#include "tensorflow/compiler/xla/service/hlo_sharding.h"
#include "tensorflow/compiler/xla/service/name_uniquer.h"
#include "tensorflow/compiler/xla/types.h"
#include "tensorflow/compiler/xla/xla_data.pb.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow/core/lib/core/stringpiece.h"
#include "tensorflow/core/lib/gtl/array_slice.h"
#include "tensorflow/core/lib/gtl/flatmap.h"
#include "tensorflow/core/lib/gtl/inlined_vector.h"
#include "tensorflow/core/lib/gtl/iterator_range.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/platform/macros.h"
#include "tensorflow/core/platform/protobuf.h"
#include "tensorflow/core/platform/types.h"

namespace xla {

class HloComputation;
class HloModule;

// A bunch of switches that control how the hlo text should be printed.
class HloPrintOptions {
 public:
  enum class PrintSubcomputationMode {
    kOff,         // Do not print anything about subcomputations.
    kNameOnly,    // Only print the name of subcomputations.
    kFullBodies,  // Print the full bodies of subcomputations.
  };

  // Constructs the default print options: don't print large constants, don't
  // compact operands, no indentation.
  HloPrintOptions()
      : print_large_constants_(false),
        print_subcomputation_mode_(PrintSubcomputationMode::kNameOnly),
        print_metadata_(true),
        print_backend_config_(true),
        compact_operands_(false),
        print_operand_shape_(true),
        print_program_shape_(true),
        print_percent_(true),
        canonicalize_instruction_names_(false),
        indent_amount_(0),
        is_in_nested_computation_(false) {}

  static HloPrintOptions ShortParsable() {
    return HloPrintOptions()
        .set_print_large_constants(true)
        .set_print_subcomputation_mode(PrintSubcomputationMode::kNameOnly)
        .set_print_metadata(false)
        .set_print_backend_config(false)
        .set_print_operand_shape(false)
        .set_print_program_shape(false)
        .set_print_percent(false);
  }

  // Options to produce the canonical string representing an isomorphic
  // computation graph.
  static HloPrintOptions Canonical() {
    return HloPrintOptions()
        .set_print_subcomputation_mode(PrintSubcomputationMode::kFullBodies)
        .set_print_metadata(false)
        .set_compact_operands(true)
        .set_print_operand_shape(true)
        .set_print_program_shape(false)
        .set_print_percent(false)
        .set_canonicalize_instruction_names(true);
  }

  // If true, large constants will be printed out.
  HloPrintOptions& set_print_large_constants(bool value) {
    print_large_constants_ = value;
    return *this;
  }

  HloPrintOptions& set_print_subcomputation_mode(
      PrintSubcomputationMode value) {
    print_subcomputation_mode_ = value;
    return *this;
  }

  // If true, metadata will be printed.
  HloPrintOptions& set_print_metadata(bool value) {
    print_metadata_ = value;
    return *this;
  }

  // If true, backend_config will be printed.
  HloPrintOptions& set_print_backend_config(bool value) {
    print_backend_config_ = value;
    return *this;
  }

  // If true, operands' shapes will be printed.
  HloPrintOptions& set_print_operand_shape(bool value) {
    print_operand_shape_ = value;
    return *this;
  }

  // If true, program shape of hlo computations will be printed.
  HloPrintOptions& set_print_program_shape(bool value) {
    print_program_shape_ = value;
    return *this;
  }

  // If true, names will be printed with prefix '%'.
  HloPrintOptions& set_print_percent(bool value) {
    print_percent_ = value;
    return *this;
  }

  // If true, only a part of operands will be printed out, and their names will
  // be omitted (note that in this case the text will not be parsable).
  HloPrintOptions& set_compact_operands(bool value) {
    compact_operands_ = value;
    return *this;
  }

  // If true, canonicalizes instructions' name. Instead of using "%foo.1" as
  // the name of an instruction, we use "%tmp_1", "%tmp_2" etc.
  HloPrintOptions& set_canonicalize_instruction_names(bool value) {
    canonicalize_instruction_names_ = value;
    return *this;
  }

  // The indent of the hlo text block.
  HloPrintOptions& set_indent_amount(int value) {
    indent_amount_ = value;
    return *this;
  }

  // If true, indicates the instruction being printed is inside a nested
  // computation.
  HloPrintOptions& set_is_in_nested_computation(bool value) {
    is_in_nested_computation_ = value;
    return *this;
  }

  bool print_large_constants() const { return print_large_constants_; }
  PrintSubcomputationMode print_subcomputation_mode() const {
    return print_subcomputation_mode_;
  }
  bool print_metadata() const { return print_metadata_; }
  bool print_backend_config() const { return print_metadata_; }
  bool compact_operands() const { return compact_operands_; }
  bool print_operand_shape() const { return print_operand_shape_; }
  bool print_program_shape() const { return print_program_shape_; }
  bool print_percent() const { return print_percent_; }
  bool canonicalize_instruction_names() const {
    return canonicalize_instruction_names_;
  }
  int indent_amount() const { return indent_amount_; }
  int is_in_nested_computation() const { return is_in_nested_computation_; }

 private:
  bool print_large_constants_;
  PrintSubcomputationMode print_subcomputation_mode_;
  bool print_metadata_;
  bool print_backend_config_;
  bool compact_operands_;
  bool print_operand_shape_;
  bool print_program_shape_;
  bool print_percent_;
  bool canonicalize_instruction_names_;
  int indent_amount_;
  bool is_in_nested_computation_;
};

// For canonical string output, we need to have a canonical way to rename
// each instruction and its operands. Each operand is renamed as "tmp_<xxx>",
// where <xxx> is an index starting from 0.
class CanonicalNameMap {
 public:
  CanonicalNameMap() : index(0) {}

  string LookupOrInsert(const string& old_name) {
    auto iter = canonical_name_map.find(old_name);
    if (iter != canonical_name_map.end()) {
      return iter->second;
    }

    string new_name = tensorflow::strings::StrCat("tmp_", index++);
    canonical_name_map[old_name] = new_name;
    return new_name;
  }
  void Clear() {
    canonical_name_map.clear();
    index = 0;
  }

 private:
  int64 index;
  tensorflow::gtl::FlatMap<string, string> canonical_name_map;
};

// HLO instructions are the atomic unit of the high-level compiler's IR.
//
// HloInstructions live inside of an HloComputation, which is analogous to a
// function in other programming languages.  Nodes have no total order within
// their computation.  Instead, they have a partial ordering determined by their
// data and control dependencies.
//
// HLO does not have basic blocks or explicit "branch" instructions.  Instead,
// certain HloInstructions -- namely, kWhile, kConditional, and kCall -- encode
// control flow.  For example, the kConditional HLO executes one of two possible
// computations, depending on the runtime value of a predicate.
//
// HLO is pure (mostly).  It has no concept of mutable state.  Instead, data
// values are produced by one HLO and flow into consumers across dependency
// edges.
class HloInstruction {
 public:
  // A fusion node computes the same value a call to its fusion computation
  // would compute.  However, the choice of fusion kind dictates codegen
  // strategy for the backend.
  //
  // To generate code for a kFusion HloInstruction, most backends do something
  // like the following:
  //
  // 1) Identify the "primary" HloInstruction of the fused computation.
  // 2) Emit code that does the work of the primary node, creating its inputs
  //    and transforming its outputs as specified by the fused computation.
  //
  // In step (2), the code emitted is usually similar to the code that would be
  // emitted for an *unfused* version of the primary node, except that
  //
  //  - when the primary node reads an element of one of its operands, instead
  //    of loading the value from memory, it *computes* the value based on the
  //    contents of the fused computation.
  //  - when the primary node outputs a value, instead of storing it to memory,
  //    it forwards the value to its users, which then perform additional
  //    computations before the value is finally stored to memory at the root of
  //    the fusion node.
  //
  // An HloInstruction's FusionKind helps us find the kFusion instruction's
  // primary node, and can also affect how we generate code in step (2).
  //
  //  - kInput: The primary node is the root of the fused instruction.
  //
  //  - kOutput: The primary node is not the root of the fused instruction.
  //    This fusion kind requires that one operand buffer of the fusion
  //    instruction be able to alias the output buffer.  This constraint is
  //    usually enough to let backends find the primary node unambiguously.
  //
  //  - kLoop: The primary node is the root of the fused computation, but,
  //    unlike in input fusion, we prescribe a specific implementation for
  //    codegen.  Rather than generating code that looks like the code we'd emit
  //    for an unfused version of the primary/root node, we emit code that
  //    generates one element of the root at a time.
  //
  //  - kCustom: Custom category for backend-specific fusions that don't fit
  //    into the above patterns.
  //
  // Not all backends support all fusion kinds, and given a particular fused
  // computation, it's not in general safe to change its fusion kind.  Creation
  // of fusion nodes is always backend-specific.
  //
  // For elementwise ops (e.g. kAdd), most backends would emit a
  // one-element-at-a-time implementation for the unfused version, so loop
  // fusion and input fusion are probably equivalent if the root node is
  // elementwise.  They're not necessarily equivalent e.g. for kReduce, where an
  // implementation might emit something more sophisticated for an unfused or
  // input-fusion reduce, but will emit the naive code that reduces one element
  // at a time for loop fusion with a reduce as the root.
  //
  // Another way to think of loop fusion is that it's equivalent to input
  // fusion, but where the root node is an implicit identity node, whose
  // unfused implementation is "read one element, write one element".
  //
  // TODO(b/79869434): This categorization scheme is not great.  For one thing,
  // input and loop fusion are basically the same thing: There is no reason for
  // the HLO to encode backend-specific decisions about how e.g. a reduce that's
  // the root of a fusion should be lowered.  In addition, this scheme as
  // written doesn't work for multi-output fusion, where the primary node is
  // never actually the root (which is a kTuple instruction that gathers the
  // multiple outputs of the fusion).
  enum class FusionKind {
    kLoop,
    kInput,
    kOutput,
    kCustom,
  };

  virtual ~HloInstruction();

  // Creates an instruction from the given proto. Arguments:
  //
  //   proto: the proto to convert from.
  //   instruction_map: a map from instruction id to HloInstruction*. This map
  //     must contain all operands of the newly constructed instruction.
  //   computation_map: a map from computation id to HloComputation*. This map
  //     must contain all computations which the newly constructed instruction
  //     calls.
  static StatusOr<std::unique_ptr<HloInstruction>> CreateFromProto(
      const HloInstructionProto& proto,
      const tensorflow::gtl::FlatMap<int64, HloInstruction*>& instruction_map,
      const tensorflow::gtl::FlatMap<int64, HloComputation*>& computation_map);

  // Creates a parameter-retrieving instruction.
  static std::unique_ptr<HloInstruction> CreateParameter(int64 parameter_number,
                                                         const Shape& shape,
                                                         const string& name);

  // Creates a literal constant instruction.
  static std::unique_ptr<HloInstruction> CreateConstant(
      std::unique_ptr<Literal> literal);

  // Creates a get tuple element instruction.
  static std::unique_ptr<HloInstruction> CreateGetTupleElement(
      const Shape& shape, HloInstruction* operand, int64 index);

  // Creates a trace instruction that logs the input operand in the computation.
  static std::unique_ptr<HloInstruction> CreateTrace(const string& tag,
                                                     HloInstruction* operand);

  // Creates a random number generation instruction that fills a shape with
  // random numbers from a given distribution.
  static std::unique_ptr<HloInstruction> CreateRng(
      const Shape& shape, RandomDistribution distribution,
      tensorflow::gtl::ArraySlice<HloInstruction*> parameters);

  // Creates a unary instruction (one operand).
  // Precondition: opcode must be a legitimate unary operation.
  static std::unique_ptr<HloInstruction> CreateUnary(const Shape& shape,
                                                     HloOpcode opcode,
                                                     HloInstruction* operand);

  // Creates a binary instruction (two operands).
  // Precondition: opcode must be a legitimate binary operation.
  static std::unique_ptr<HloInstruction> CreateBinary(const Shape& shape,
                                                      HloOpcode opcode,
                                                      HloInstruction* lhs,
                                                      HloInstruction* rhs);

  // Creates a ternary instruction (three operands).
  // Precondition: opcode must be a legitimate ternary operation.
  static std::unique_ptr<HloInstruction> CreateTernary(const Shape& shape,
                                                       HloOpcode opcode,
                                                       HloInstruction* lhs,
                                                       HloInstruction* rhs,
                                                       HloInstruction* ehs);

  // Creates a variadic instruction (variable number of operands).
  // Precondition: opcode must be a legitimate variadic operation.
  static std::unique_ptr<HloInstruction> CreateVariadic(
      const Shape& shape, HloOpcode opcode,
      tensorflow::gtl::ArraySlice<HloInstruction*> operands);

  // Creates a map instruction, where the computation (given by the handle) is
  // applied element-wise to every element in operands (across the operands,
  // at a given index) with the same `static_operands`.
  static std::unique_ptr<HloInstruction> CreateMap(
      const Shape& shape, tensorflow::gtl::ArraySlice<HloInstruction*> operands,
      HloComputation* map_computation,
      tensorflow::gtl::ArraySlice<HloInstruction*> static_operands = {});

  // Creates a convolution op, where rhs is the convolutional filter
  // and window describes how the filter is applied to lhs.
  static std::unique_ptr<HloInstruction> CreateConvolve(
      const Shape& shape, HloInstruction* lhs, HloInstruction* rhs,
      const Window& window,
      const ConvolutionDimensionNumbers& dimension_numbers);

  // Creates an FFT op, of the type indicated by fft_type.
  static std::unique_ptr<HloInstruction> CreateFft(
      const Shape& shape, HloInstruction* operand, FftType fft_type,
      tensorflow::gtl::ArraySlice<int64> fft_length);

  // Creates a dot op with operands 'lhs' and 'rhs' with contracting and batch
  // dimensions specified in 'dimension_numbers'.
  static std::unique_ptr<HloInstruction> CreateDot(
      const Shape& shape, HloInstruction* lhs, HloInstruction* rhs,
      const DotDimensionNumbers& dimension_numbers);

  // Creates a dot op with operands 'lhs' and 'rhs' that contracts dimension 1
  // of the LHS with dimension 0 of the RHS with no batch dimensions.  Both LHS
  // and the RHS must be of rank 2.
  static std::unique_ptr<HloInstruction> CreateCanonicalDot(
      const Shape& shape, HloInstruction* lhs, HloInstruction* rhs);

  // Creates a reduce-precision op, where operand is the data to reduce in
  // precision, and exponent_bits and mantissa_bits describe the precision to
  // reduce it to.
  static std::unique_ptr<HloInstruction> CreateReducePrecision(
      const Shape& shape, HloInstruction* operand, const int exponent_bits,
      const int mantissa_bits);

  // Creates a cross replica reduction op.
  //
  // `reduction_computation`: the reduction function.
  //
  // `replica_group_ids`: maps replica ids to subgroup ids. If empty, all
  // replicas belong to one group. Allreduce will be applied within subgroups.
  // For example, we have 4 replicas, then replica_group_ids={0,1,0,1} means,
  // replica 0 and 2 are in subgroup 0, replica 1 and 3 are in subgroup 1.
  //
  // `channel_id`: for Allreduce nodes from different models, if they have the
  // same channel_id, they will be 'Allreduce'd. If empty, Allreduce will not be
  // applied cross models.
  //
  // TODO(b/79737069): Rename this to AllReduce.
  static std::unique_ptr<HloInstruction> CreateCrossReplicaSum(
      const Shape& shape, tensorflow::gtl::ArraySlice<HloInstruction*> operands,
      HloComputation* reduce_computation,
      tensorflow::gtl::ArraySlice<int64> replica_group_ids = {},
      const tensorflow::gtl::optional<int64>& channel_id =
          tensorflow::gtl::nullopt);

  // Creates a conversion instruction, where operand is the data to convert and
  // shape is the target shape for the conversion.
  static std::unique_ptr<HloInstruction> CreateConvert(const Shape& shape,
                                                       HloInstruction* operand);

  // Creates a bitcast conversion instruction, where operand is the data to
  // convert and shape is the target shape for the conversion.
  static std::unique_ptr<HloInstruction> CreateBitcastConvert(
      const Shape& shape, HloInstruction* operand);

  // Creates an infeed instruction, which reads data of the given shape from the
  // Infeed interface of the device.
  static std::unique_ptr<HloInstruction> CreateInfeed(const Shape& shape,
                                                      const string& config);

  // Creates an outfeed instruction, which outputs data.
  static std::unique_ptr<HloInstruction> CreateOutfeed(
      const Shape& shape, HloInstruction* operand,
      tensorflow::StringPiece outfeed_config);

  // Creates an asynchronous send instruction with the given channel id, which
  // initiates sending the operand data to a unique receive instruction in
  // another computation that has the same channel id.
  static std::unique_ptr<HloInstruction> CreateSend(HloInstruction* operand,
                                                    int64 channel_id);

  // Blocks until data transfer for the Send instruction (operand) is complete.
  // The operand must be kSend.
  static std::unique_ptr<HloInstruction> CreateSendDone(
      HloInstruction* operand);

  // Creates an asynchronous receive instruction with the given channel id,
  // which allocates resources to receive data of the given shape from a unique
  // send instruction in another computation that has the same channel id.
  static std::unique_ptr<HloInstruction> CreateRecv(const Shape& shape,
                                                    int64 channel_id);

  // Blocks until data transfer for the Recv instruction (operand) is complete
  // and returns the receive buffer. The operand must be kRecv.
  static std::unique_ptr<HloInstruction> CreateRecvDone(
      HloInstruction* operand);

  // Creates a slice instruction, where the operand is sliced by the given
  // start/limit indices.
  static std::unique_ptr<HloInstruction> CreateSlice(
      const Shape& shape, HloInstruction* operand,
      tensorflow::gtl::ArraySlice<int64> start_indices,
      tensorflow::gtl::ArraySlice<int64> limit_indices,
      tensorflow::gtl::ArraySlice<int64> strides);

  // Creates a slice instruction, where the first operand is sliced by
  // start indices specified in the second operand, and by size specified in
  // 'slice_sizes'.
  static std::unique_ptr<HloInstruction> CreateDynamicSlice(
      const Shape& shape, HloInstruction* operand,
      HloInstruction* start_indices,
      tensorflow::gtl::ArraySlice<int64> slice_sizes);

  // Creates a dynamic update slice instruction, which updates a slice
  // of 'operand' with 'update' and 'start_indices'.
  static std::unique_ptr<HloInstruction> CreateDynamicUpdateSlice(
      const Shape& shape, HloInstruction* operand, HloInstruction* update,
      HloInstruction* start_indices);

  // Creates a concatenate instruction, where the operands are concatenated on
  // the provided dimension.
  static std::unique_ptr<HloInstruction> CreateConcatenate(
      const Shape& shape, tensorflow::gtl::ArraySlice<HloInstruction*> operands,
      int64 dimension);

  // Creates a reduce instruction, where the computation (given by the handle)
  // is applied successively to every element in operand. That is, if f is the
  // function to apply (which either takes 2 [accumulator, value] or 3
  // [accumulator, index, value] arguments) and init is a reduction operator
  // specified initial value (for example, 0 for addition), then this operation
  // will compute:
  //   f(f(init, [index0], value0), [index1], value1), ...)
  static std::unique_ptr<HloInstruction> CreateReduce(
      const Shape& shape, HloInstruction* operand, HloInstruction* init_value,
      tensorflow::gtl::ArraySlice<int64> dimensions_to_reduce,
      HloComputation* reduce_computation);

  // Creates a reduce-window instruction, where the computation (given
  // by the handle) is applied window-wise at each valid window
  // position in the operand.
  static std::unique_ptr<HloInstruction> CreateReduceWindow(
      const Shape& shape, HloInstruction* operand, HloInstruction* init_value,
      const Window& window, HloComputation* reduce_computation);

  // Creates a batch-norm-training instruction.
  static std::unique_ptr<HloInstruction> CreateBatchNormTraining(
      const Shape& shape, HloInstruction* operand, HloInstruction* scale,
      HloInstruction* offset, float epsilon, int64 feature_index);

  // Creates a batch-norm-inference instruction.
  static std::unique_ptr<HloInstruction> CreateBatchNormInference(
      const Shape& shape, HloInstruction* operand, HloInstruction* scale,
      HloInstruction* offset, HloInstruction* mean, HloInstruction* variance,
      float epsilon, int64 feature_index);

  // Creates a batch-norm-grad instruction.
  static std::unique_ptr<HloInstruction> CreateBatchNormGrad(
      const Shape& shape, HloInstruction* operand, HloInstruction* scale,
      HloInstruction* mean, HloInstruction* variance,
      HloInstruction* grad_output, float epsilon, int64 feature_index);

  // Creates a scatter computation that scatters the `source` array to the
  // selected indices of each window.
  static std::unique_ptr<HloInstruction> CreateSelectAndScatter(
      const Shape& shape, HloInstruction* operand, HloComputation* select,
      const Window& window, HloInstruction* source, HloInstruction* init_value,
      HloComputation* scatter);

  // Creates a broadcast instruction.
  static std::unique_ptr<HloInstruction> CreateBroadcast(
      const Shape& shape, HloInstruction* operand,
      tensorflow::gtl::ArraySlice<int64> broadcast_dimensions);

  // Creates a sequence of instructions that performs an explicit broadcast of
  // the operand to the target shape.
  //
  // Interior HLOs are passed to "adder", but the "root" HLO of the sequence is
  // returned as a unique_ptr for API consistency with other factory methods in
  // this interface.
  //
  // TODO(b/72173833) Ideally HloComputations would always be present, and so
  // the adder being passed by the caller would not be necessary.
  static std::unique_ptr<HloInstruction> CreateBroadcastSequence(
      const Shape& output_shape, HloInstruction* operand,
      const std::function<HloInstruction*(std::unique_ptr<HloInstruction>)>&
          adder);

  // Creates a pad instruction, where the operand is padded on the edges and
  // between the elements with the given padding value.
  static std::unique_ptr<HloInstruction> CreatePad(
      const Shape& shape, HloInstruction* operand,
      HloInstruction* padding_value, const PaddingConfig& padding_config);

  // Creates a reshape instruction, where the operand is flattened row-major
  // order and then reshaped to the given result shape.
  static std::unique_ptr<HloInstruction> CreateReshape(const Shape& shape,
                                                       HloInstruction* operand);

  // Creates a transpose instruction which permutes the operand dimensions.
  static std::unique_ptr<HloInstruction> CreateTranspose(
      const Shape& shape, HloInstruction* operand,
      tensorflow::gtl::ArraySlice<int64> dimensions);

  // Creates a while instruction, given a condition computation, a body
  // computation, and the initial value for the input of the computations. For
  // example, shape: S32, condition: i -> i < 1000, body: i -> i * 2, init: 1
  // corresponds to the C code below.
  // int32 i = 1; int32 result = while(i < 1000) { i = i * 2 }
  static std::unique_ptr<HloInstruction> CreateWhile(const Shape& shape,
                                                     HloComputation* condition,
                                                     HloComputation* body,
                                                     HloInstruction* init);

  static std::unique_ptr<HloInstruction> CreateConditional(
      const Shape& shape, HloInstruction* pred,
      HloInstruction* true_computation_arg, HloComputation* true_computation,
      HloInstruction* false_computation_arg, HloComputation* false_computation);

  static std::unique_ptr<HloInstruction> CreateGather(
      const Shape& shape, HloInstruction* operand,
      HloInstruction* gather_indices,
      const GatherDimensionNumbers& gather_dim_numbers,
      tensorflow::gtl::ArraySlice<int64> window_bounds);

  // Creates a kDomain instruction which delimits an HLO domain which have
  // the provided user and operand side metadata.
  static std::unique_ptr<HloInstruction> CreateDomain(
      const Shape& shape, HloInstruction* operand,
      std::unique_ptr<DomainMetadata> operand_side_metadata,
      std::unique_ptr<DomainMetadata> user_side_metadata);

  // Creates a fusion instruction. A fusion instruction contains one or more
  // fused instructions forming an expression with a single root
  // "fused_root". Additional instructions can be added to the fusion
  // instruction with the method FuseInstruction.
  static std::unique_ptr<HloInstruction> CreateFusion(
      const Shape& shape, FusionKind fusion_kind, HloInstruction* fused_root);

  static std::unique_ptr<HloInstruction> CreateFusion(
      const Shape& shape, FusionKind fusion_kind,
      tensorflow::gtl::ArraySlice<HloInstruction*> operands,
      HloComputation* fusion_computation);

  // Creates a call instruction that applies the given computation on the given
  // operands. "shape" is the resultant shape.
  static std::unique_ptr<HloInstruction> CreateCall(
      const Shape& shape, tensorflow::gtl::ArraySlice<HloInstruction*> operands,
      HloComputation* computation);

  // Creates a custom call instruction that applies the given custom call target
  // to the given operands. "shape" is the resultant shape.
  static std::unique_ptr<HloInstruction> CreateCustomCall(
      const Shape& shape, tensorflow::gtl::ArraySlice<HloInstruction*> operands,
      tensorflow::StringPiece custom_call_target);

  // Creates a HostCompute instruction, which records host-side control and
  // data dependencies for use in instruction scheduling.
  static std::unique_ptr<HloInstruction> CreateHostCompute(
      const Shape& shape, tensorflow::gtl::ArraySlice<HloInstruction*> operands,
      tensorflow::StringPiece channel_name, const int64 cost_estimate_ns);

  // Creates a tuple instruction with the given elements. This is a convenience
  // wrapper around CreateVariadic.
  static std::unique_ptr<HloInstruction> CreateTuple(
      tensorflow::gtl::ArraySlice<HloInstruction*> elements);

  // Creates a reverse instruction, which reverses the order of the elements
  // in the specified dimensions.
  static std::unique_ptr<HloInstruction> CreateReverse(
      const Shape& shape, HloInstruction* operand,
      tensorflow::gtl::ArraySlice<int64> dimensions);

  // Creates an instance of GatherDimensionNumbers.
  static GatherDimensionNumbers MakeGatherDimNumbers(
      tensorflow::gtl::ArraySlice<int64> output_window_dims,
      tensorflow::gtl::ArraySlice<int64> elided_window_dims,
      tensorflow::gtl::ArraySlice<int64> gather_dims_to_operand_dims,
      int64 index_vector_dim);

  // Returns the opcode for this instruction.
  HloOpcode opcode() const { return opcode_; }

  // Returns true if this instruction has a side effect, irrespective of whether
  // any called computations may contain an instruction with side effects.
  bool HasSideEffectNoRecurse() const;

  // Returns true if this instruction has a side effect. An instruction has a
  // side effect if it uses certain opcodes or calls a computation with a side
  // effect.
  bool HasSideEffect() const;

  // Returns the result shape of this instruction.
  const Shape& shape() const;

  // Returns the (mutable) result shape of this instruction.
  Shape* mutable_shape() { return &shape_; }

  // Returns the ith operand to this instruction.
  const HloInstruction* operand(int64 i) const;

  // Returns the ith operand to this instruction.
  HloInstruction* mutable_operand(int64 i);

  // Returns the number of operands to this instruction.
  int64 operand_count() const { return operands_.size(); }

  // Returns the vector of operands of this instruction.
  using InstructionVector = tensorflow::gtl::InlinedVector<HloInstruction*, 2>;
  const InstructionVector& operands() const { return operands_; }

  // Returns the vector of unique operands, in the same order they are found
  // within the operand vector.
  InstructionVector unique_operands() const;

  // Returns the index of 'target' in the operands sequence.
  // Precondition: target must be an operand (or a fatal error will occur).
  int64 operand_index(const HloInstruction* target) const;

  // Returns the number of users of this instruction.
  int64 user_count() const { return users_.size(); }

  // Returns the users of this instruction.
  const std::vector<HloInstruction*>& users() const { return users_; }

  // Returns true if this instruction is a user of 'instruction'.
  bool IsUserOf(const HloInstruction* instruction) const {
    return ContainsKey(instruction->user_set_, this);
  }

  // Adds a control dependency from this instruction to the given
  // instruction. This instruction becomes a control predecessor of
  // 'instruction', and 'instruction' becomes a control successor of this
  // instruction. Returns an error status if either of the given instructions
  // does not belong to the same computation.
  //
  // This is used to enforce an additional ordering requirement that is not
  // captured by normal data dependencies, such as ordering among Send or Recv
  // operations to avoid deadlock.
  Status AddControlDependencyTo(HloInstruction* instruction);

  // Removes a previously added control dependency from this instruction to
  // 'instruction'.
  Status RemoveControlDependencyTo(HloInstruction* instruction);

  // Drops all control predecessors and successors from this HLO instruction.
  Status DropAllControlDeps();

  // Copies the control predecessors and successors on this HLO instruction to
  // `inst`.  Does not do a deep copy so this makes sense only if `inst` and
  // this HLO are in the same module.
  //
  // Depending on the use cases we see in practice, in the future we may
  // consider folding the logic here into Clone, CloneWithNewOperands and
  // ReplaceAllUsesWith by treating control dependencies like data dependencies.
  Status CopyAllControlDepsFrom(const HloInstruction* inst);

  // Returns the set of control predecessors (successors) of this
  // instruction. Control predecessors (successors) must execute before (after)
  // the current instruction.
  const std::vector<HloInstruction*>& control_predecessors() const {
    return control_predecessors_;
  }
  const std::vector<HloInstruction*>& control_successors() const {
    return control_successors_;
  }

  // Returns true if "other" performs the same computation as this instruction.
  bool Identical(
      const HloInstruction& other,
      const std::function<bool(const HloInstruction*, const HloInstruction*)>&
          eq_operands = std::equal_to<const HloInstruction*>(),
      const std::function<bool(const HloComputation*, const HloComputation*)>&
          eq_computations = std::equal_to<const HloComputation*>(),
      bool layout_sensitive = true) const {
    // An instruction is always identical to itself.
    if (this == &other) {
      return true;
    }

    // Identical instruction must have the same opcode, shape, and identical
    // operands.
    if (opcode() != other.opcode()) {
      return false;
    }
    if (!(layout_sensitive ? ShapeUtil::Equal(shape(), other.shape())
                           : ShapeUtil::Compatible(shape(), other.shape()))) {
      return false;
    }
    if (operands().size() != other.operands().size()) {
      return false;
    }

    // Use an explicit loop rather than ContainerEquals, because copying around
    // std::functions may be too expensive in some cases.
    for (size_t i = 0; i < operands().size(); ++i) {
      if (!eq_operands(operand(i), other.operand(i))) {
        return false;
      }
    }

    if (backend_config_ != other.backend_config_) {
      return false;
    }

    return IdenticalSlowPath(other, eq_computations);
  }

  // Returns whether the instruction has a constant operand.
  bool HasConstantOperand() const;

  // Returns whether this instruction does a rank-2 transposition.
  bool IsRank2Transpose() const;

  // Replaces the use of this instruction in "user" with "new_producer". Note
  // that there might be multiple uses of this instruction in "user"; all will
  // be replaced.
  Status ReplaceUseWith(HloInstruction* user, HloInstruction* new_producer);

  // Replaces the specified operand with new_operand.
  Status ReplaceOperandWith(int64 operand_no, HloInstruction* new_operand);

  // Replaces all uses of this instruction with the new producer. If
  // new_producer is a user of this instruction then new_producer remains a use
  // of this instruction to avoid introducing cycles into the graph.
  //
  // If this instruction is the root of its computation, sets the computation's
  // root to new_producer.
  Status ReplaceAllUsesWith(HloInstruction* new_producer);

  // Detaches an instruction from its operands. That is, remove the instruction
  // from each operand's user set. This should only be called prior to
  // deallocating the instruction.
  //
  // TODO(b/78305363): Make this automatic when deleting an instruction.
  void DetachFromOperands();

  // Performs a postorder DFS visit using this node as the root. If
  // call_finish_visit is true, then DfsHloVisitor::FinishVisit is called when
  // complete. If ignore_control_predecessors is true, instructions only
  // reachable via control dependencies will not be visited, and the postorder
  // will not take control dependencies into account. It is as if the control
  // dependencies didn't exist in the graph at all.
  template <typename HloInstructionPtr>
  Status Accept(DfsHloVisitorBase<HloInstructionPtr>* visitor,
                bool call_finish_visit = true,
                bool ignore_control_predecessors = false);
  Status Accept(ConstDfsHloVisitor* visitor, bool call_finish_visit = true,
                bool ignore_control_predecessors = false) const {
    return const_cast<HloInstruction*>(this)->Accept(
        visitor, call_finish_visit, ignore_control_predecessors);
  }

  // Same as Accept() above, but the order of operand and control predecessor
  // visitation is determined by the given operand order; if compare(A, B) ==
  // true, A is visited before B.
  using CompareFunction =
      std::function<bool(const HloInstruction*, const HloInstruction*)>;
  Status AcceptWithOperandOrder(DfsHloVisitor* visitor,
                                const CompareFunction& operand_order,
                                bool call_finish_visit = true);

  // Performs a postorder DFS visit using this node as the root. Calls the given
  // visitor function at each instruction.
  Status Accept(const std::function<Status(HloInstruction*)>& visitor_func);
  Status Accept(
      const std::function<Status(const HloInstruction*)>& visitor_func) const;

  // Visits all instructions rooted at this instruction using the given visitor
  // in the given order. 'order' must contain at least the set of instructions
  // rooted at this node (ie, those accessible from a DFS traversal from this
  // instruction). Instructions contained in 'order' which are not in the set of
  // instructions rooted at this node are ignored. 'order' must also be a valid
  // topological sort of these instructions (defs appear before uses) though
  // need not be a DFS post-order.
  Status AcceptOrdered(DfsHloVisitor* visitor,
                       const std::vector<const HloInstruction*>& order);

  // Visit this instruction and only this instruction with the given visitor.
  template <typename HloInstructionPtr>
  Status Visit(DfsHloVisitorBase<HloInstructionPtr>* visitor);

  // Returns the literal associated with this instruction.
  //
  // Note: only constant and parameter opcodes have an associated literal.
  const Literal& literal() const;

  // Returns whether there is literal associated with this instruction.
  bool HasLiteral() const;

  // Returns the parameter number associated with this instruction.
  //
  // Note: only parameter opcodes have an associated parameter number.
  int64 parameter_number() const {
    CHECK_EQ(HloOpcode::kParameter, opcode_);
    return parameter_number_;
  }

  // Returns the dimension sizes or numbers associated with this instruction.
  //
  // Precondition: opcode() is one of: concatenate, reduce, broadcast, reshape,
  // and reverse.
  const std::vector<int64>& dimensions() const;
  int64 dimensions(int64 index) const;

  // Accessor for the dimension in which a concatenate HLO should occur.
  // Precondition: opcode() == HloOpcode::kConcatenate
  int64 concatenate_dimension() const;

  // Returns the tuple index associated with this instruction.
  //
  // Precondition: opcode() == HloOpcode::kGetTupleElement
  int64 tuple_index() const;

  // Returns the first non-GetTupleElement ancestor instruction of 'hlo'.
  // If the first non-GTE ancestor is tuple-shaped, populates 'index' with the
  // (possibly nested) tuple indices used on the path from ancestor to 'hlo'.
  std::pair<const HloInstruction*, ShapeIndex> LatestNonGteAncestorAndIndex()
      const;

  std::pair<HloInstruction*, ShapeIndex> LatestNonGteAncestorAndIndex() {
    auto rv =
        const_cast<const HloInstruction*>(this)->LatestNonGteAncestorAndIndex();
    return {const_cast<HloInstruction*>(rv.first), rv.second};
  }

  // Same as LatestNonGteAncestorAndIndex, but just returns the HloInstruction.
  const HloInstruction* LatestNonGteAncestor() const;

  HloInstruction* LatestNonGteAncestor() {
    return const_cast<HloInstruction*>(
        const_cast<const HloInstruction*>(this)->LatestNonGteAncestor());
  }

  // Gets/sets the to_apply HloComputation for Call, Map, Reduce, etc.
  // The setter should only be called by HloModule or HloComputation methods.
  //
  // Precondition: The instruction has a valid to_apply_ field.
  HloComputation* to_apply() const;
  void set_to_apply(HloComputation* to_apply);

  // Returns the custom_call_target for CustomCall.
  // Precondition: opcode() == HloOpcode::kCustomCall
  const string& custom_call_target() const;

  // Returns the config for the Outfeed instruction.
  // Precondition: opcode() == HloOpcode::kOutfeed
  const string& outfeed_config() const;

  // Returns the shape for the Outfeed instruction.
  // Precondition: opcode() == HloOpcode::kOutfeed
  const Shape& outfeed_shape() const;

  // Gets/sets the while_condition or while_body HloComputation for While. The
  // setters should only be called by HloModule or HloComputation methods.
  //
  // Precondition: The instruction is a While instruction.
  HloComputation* while_condition() const;
  HloComputation* while_body() const;
  void set_while_condition(HloComputation* while_condition);
  void set_while_body(HloComputation* while_body);

  // Gets/sets the select or scatter HloComputation for SelectAndScatter. The
  // setters should only be called by HloModule or HloComputation methods.
  //
  // Precondition: opcode() == HloOpcode::kSelectAndScatter.
  HloComputation* select() const;
  HloComputation* scatter() const;
  void set_select(HloComputation* select);
  void set_scatter(HloComputation* scatter);

  // Gets/sets the true and false HloComputation for Conditional. The setters
  // should only be called by HloModule or HloComputation methods.
  //
  // Precondition: The instruction is a Conditional instruction.
  HloComputation* true_computation() const;
  HloComputation* false_computation() const;
  void set_true_computation(HloComputation* true_computation);
  void set_false_computation(HloComputation* false_computation);

  // Returns a string for the signature of this instruction if considered as a
  // function, e.g. the signature of an F32 add is (F32, F32) -> F32.
  string SignatureString() const;

  // Returns a debugging string that represents this instruction.
  //
  // (We express the default options using an overload rather than a default
  // param because gdb ignores default params, but does resolve overloads.)
  //
  // TODO(b/73348663): Make ToString() adaptive to the size of the string by
  // default, backing off on providing full information for very large strings,
  // or provide a different name for a ToString-like function that does that.
  string ToString() const { return ToString(HloPrintOptions()); }
  string ToString(const HloPrintOptions& options) const;

  // Components of the ToString() representation:

  // Returns a string representation of the operand list.
  string OperandsToString(const HloPrintOptions& options) const;

  // Returns string representation of op-specific attributes.
  virtual std::vector<string> ExtraAttributesToString(
      const HloPrintOptions& options) const;

  // As ToString, but returns a shorter string.
  string ToShortString() const;

  // Returns a serialized representation of this instruction.
  virtual HloInstructionProto ToProto() const;

  // Returns a category for the HLO. This could be something like "convolution"
  // or "elementwise".
  string ToCategory() const;

  // Returns a logging instruction, if the output of this instruction is logged.
  //
  // Postcondition: retval == nullptr || retval->opcode() == HloOpcode::kTrace
  HloInstruction* tracing() const;
  void set_tracing(HloInstruction* trace_instruction);

  // Returns the channel id associated with the instruction. The id is
  // shared between each Send/Recv pair and is globally unique to identify each
  // channel.
  //
  // Precondition: opcode() == HloOpcode::kSend or HloOpcode::kRecv
  int64 channel_id() const { return channel_id_; }

  // Returns the channel name associated with the instruction. The name is
  // used to identify host Send/Recv operations.
  //
  // Precondition: opcode() == HloOpcode::kHostCompute
  string channel_name() const { return channel_name_; }

  // Delegates to HloBatchNormInstruction::feature_index.
  // TODO(b/80131774): Remove this code.
  int64 feature_index() const;

  // Delegates to HloBatchNormInstruction::epsilon.
  // TODO(b/80131774): Remove this code.
  float epsilon() const;

  // Returns the infeed configuration string. The infeed configuration includes
  // any metadata needed for the backend compiler (e.g., infeed buffer address)
  // and is target-dependent.
  string infeed_config() const { return infeed_config_; }
  void set_infeed_config(const string& config) { infeed_config_ = config; }

  // Returns a tag to be used in tracing.
  //
  // Precondition: opcode() == HloOpcode::kTrace
  string TracingTag() const;

  // Returns whether the instruction is a constant.
  bool IsConstant() const;

  // Returns true if this instruction is fused, ie contained within a fusion
  // instruction.
  bool IsFused() const;

  // Returns the computation for this fused instruction.
  //
  // Precondition: opcode() == HloOpcode::kFusion
  HloComputation* fused_instructions_computation() const;

  // Returns true if this instruction can be legally fused into a fusion
  // instruction.
  bool IsFusable() const;

  // Returns the root instruction of the fused expression contained within this
  // fusion instruction.
  //
  // Precondition: opcode() == HloOpcode::kFusion
  HloInstruction* fused_expression_root() const;

  // Returns the list of fused instructions inside this fusion instruction.  The
  // returned type is a range of HloInstruction*s.
  //
  // Precondition: opcode() == HloOpcode::kFusion
  const tensorflow::gtl::iterator_range<UnwrappingIterator<
      std::list<std::unique_ptr<HloInstruction>>::const_iterator>>
  fused_instructions() const;

  const tensorflow::gtl::iterator_range<
      UnwrappingIterator<std::list<std::unique_ptr<HloInstruction>>::iterator>>
  fused_instructions();

  // Gets the number of instructions inside this fusion instruction.
  //
  // Precondition: opcode() == HloOpcode::kFusion
  int64 fused_instruction_count() const;

  // Returns the fused parameter instruction in this fusion instruction
  // corresponding to the given parameter number.
  //
  // Precondition: opcode() == HloOpcode::kFusion
  HloInstruction* fused_parameter(int64 parameter_number) const;

  // Returns the vector of fused parameters inside this fusion instruction.
  //
  // Precondition: opcode() == HloOpcode::kFusion
  const std::vector<HloInstruction*>& fused_parameters() const;

  // Returns true if this instruction is a fusion instruction that generates
  // multiple outputs.
  const bool IsMultiOutputFusion() const {
    return opcode() == HloOpcode::kFusion &&
           fused_expression_root()->opcode() == HloOpcode::kTuple;
  }

  FusionKind fusion_kind() const {
    CHECK_EQ(HloOpcode::kFusion, opcode_);
    return fusion_kind_;
  }

  void set_fusion_kind(FusionKind kind) {
    CHECK_EQ(HloOpcode::kFusion, opcode_);
    fusion_kind_ = kind;
  }

  // Returns the sharding applied to this operator.
  // REQUIRES: has_sharding() is true.
  const HloSharding& sharding() const {
    CHECK(has_sharding());
    return *sharding_;
  }
  // Returns the sharding applied to this operator, or default_ if none exists.
  const HloSharding& sharding_or_default(const HloSharding& default_) const {
    return sharding_ ? *sharding_ : default_;
  }
  // Returns the sharding unique device, if any.
  tensorflow::gtl::optional<int64> sharding_unique_device() const {
    if (sharding_ == nullptr) {
      return tensorflow::gtl::optional<int64>();
    }
    auto device = sharding_->UniqueDevice();
    return device.ok() ? device.ValueOrDie()
                       : tensorflow::gtl::optional<int64>();
  }
  // Sets the sharding of this operator. Should only be called by HloModule or
  // HloComputation methods.
  void set_sharding(const HloSharding& sharding) {
    sharding_ = MakeUnique<HloSharding>(sharding);
  }
  // Sets a sharding that assigns the current instruction to device.
  void set_device_sharding(int64 device);
  // Remove any sharding from this operator.
  void clear_sharding() { sharding_ = nullptr; }
  // Return true if this operator has a sharding assigned.
  bool has_sharding() const { return sharding_ != nullptr; }
  // Checks whether the instruction has compatible sharding with the other
  // instruction.
  bool has_compatible_sharding(const HloInstruction* other) const {
    if (!has_sharding()) {
      return !other->has_sharding();
    }
    return other->has_sharding() ? sharding() == other->sharding() : false;
  }

  // Retrieves the operand side metadata of a kDomain instruction.
  const DomainMetadata& operand_side_metadata() const {
    return *operand_side_metadata_;
  }
  // Retrieves the user side metadata of a kDomain instruction.
  const DomainMetadata& user_side_metadata() const {
    return *user_side_metadata_;
  }

  // When creating a new instruction which either replaces, or shifts up (kCopy
  // insertion case), another instruction, we need to make sure the certain
  // properties of the new instruction are copied into the derived one. As of
  // today, the metadata and sharding will be propagated to the derived
  // instruction.
  void SetupDerivedInstruction(HloInstruction* derived_instruction) const;

  // Adds a new operand the fusion instruction.
  HloInstruction* AddFusionOperand(HloInstruction* new_operand);

  // Merges the fused instructions from 'instruction_to_merge' into the
  // fused instruction set of 'this', updating operands as necessary.
  //
  // Precondition: opcode() == HloOpcode::kFusion
  // Predondition: 'instruction_to_merge' must be an operand of 'this'.
  void MergeFusionInstruction(HloInstruction* instruction_to_merge);

  // Merges the fused instructions from instruction_to_merge into the fused
  // instruction set of 'this' and generates multioutput fusion instructions.
  // All the users of instruction_to_merge will be redirected to 'this'
  // instruction. instruction_to_merge will be removed from its parent
  // computation.
  //
  // Precondition: opcode() == HloOpcode::kFusion
  void MergeFusionInstructionIntoMultiOutput(
      HloInstruction* instruction_to_merge);

  // Fuses the given instruction in this fusion instruction. instruction_to_fuse
  // is cloned and the clone is placed in the fusion
  // instruction. instruction_to_fuse is unchanged. Instruction is cloned rather
  // than moved to cleanly handle the case where the instruction has a use
  // outside the fusion instruction. Moving such an instruction into a fusion
  // instruction would violate the single-result invariant of HLO instructions
  // and significantly complicate code generation.
  //
  // Precondition: this->opcode() == HloOpcode::kFusion
  HloInstruction* FuseInstruction(HloInstruction* instruction_to_fuse) {
    return FuseInstructionInternal(instruction_to_fuse);
  }

  // Fuses the given instruction in this fusion instruction and generate
  // multioutput fusion instruction. A clone of the instruction_to_fuse will
  // be part of the output of fusion instructions. The users of
  // instruction_to_fuse will be redirected to this fusion instructions.
  // instruction_to_fuse will be removed from its parent computation.
  //
  // Precondition: this->opcode() == HloOpcode::kFusion
  HloInstruction* FuseInstructionIntoMultiOutput(
      HloInstruction* instruction_to_fuse) {
    return FuseInstructionInternal(instruction_to_fuse, /* add_output */ true);
  }

  // Returns the start index in the given dimension for a slice node.
  //
  // Precondition: opcode() == HloOpcode::kSlice
  int64 slice_starts(int64 dimension) const {
    CHECK_EQ(HloOpcode::kSlice, opcode_);
    return slice_starts_[dimension];
  }
  const std::vector<int64>& slice_starts() const { return slice_starts_; }

  // Returns the (exclusive) limit index in the given dimension for a slice
  // node.
  //
  // Precondition: opcode() == HloOpcode::kSlice
  int64 slice_limits(int64 dimension) const {
    CHECK_EQ(HloOpcode::kSlice, opcode_);
    return slice_limits_[dimension];
  }
  const std::vector<int64>& slice_limits() const {
    CHECK_EQ(HloOpcode::kSlice, opcode_);
    return slice_limits_;
  }

  // Returns the stride in the given dimension for a slice node.
  //
  // Precondition: opcode() == HloOpcode::kSlice
  int64 slice_strides(int64 dimension) const {
    CHECK_EQ(HloOpcode::kSlice, opcode_);
    return slice_strides_[dimension];
  }
  const std::vector<int64>& slice_strides() const { return slice_strides_; }

  // Returns the flag that describes whether a slice must be lowered into an
  // offset into the original operand.
  bool IsInPlaceSlice() const { return is_in_place_slice_; }

  // Sets and returns the flag that describes whether a slice must be lowered
  // into an offset into the original operand.
  bool SetIsInPlaceSlice(bool value) {
    is_in_place_slice_ = value;
    return value;
  }

  // Returns the size of the slice in the given dimension for a dynamic
  // slice node.
  //
  // Precondition: opcode() == HloOpcode::kDynamicSlice
  int64 slice_sizes(int64 dimension) const {
    CHECK_EQ(HloOpcode::kDynamicSlice, opcode_);
    return dynamic_slice_sizes_[dimension];
  }
  const std::vector<int64>& dynamic_slice_sizes() const {
    CHECK_EQ(HloOpcode::kDynamicSlice, opcode_);
    return dynamic_slice_sizes_;
  }

  // Returns the number of exponent bits for a reduce-precision node.
  //
  // Precondition: opcode() == HloOpcode::kReducePrecision
  int32 exponent_bits() const {
    CHECK_EQ(HloOpcode::kReducePrecision, opcode_);
    return exponent_bits_;
  }

  // Returns the number of mantissa bits for a reduce-precision node.
  //
  // Precondition: opcode() == HloOpcode::kReducePrecision
  int32 mantissa_bits() const {
    CHECK_EQ(HloOpcode::kReducePrecision, opcode_);
    return mantissa_bits_;
  }

  // Returns data on the window in a windowed operation such as
  // convolution.
  const Window& window() const {
    CHECK(window_ != nullptr);
    return *window_;
  }

  // Sets the window data in a windowed operation such as convolution.
  void set_window(const Window& window) {
    window_ = MakeUnique<Window>(window);
  }

  // Returns the padding configuration for a pad node.
  //
  // Precondition: opcode() == HloOpcode::kPad
  const PaddingConfig& padding_config() const {
    CHECK(padding_config_ != nullptr);
    return *padding_config_;
  }

  // Returns data on the dimension numbers used for a convolution operation,
  // which may be a kConvolution instruction or a kCustomCall that implements a
  // convolution.
  const ConvolutionDimensionNumbers& convolution_dimension_numbers() const {
    CHECK(convolution_dimension_numbers_ != nullptr);
    return *convolution_dimension_numbers_;
  }

  // Sets the convolution dimension numbers on this instruction.  In general you
  // shouldn't need to call this; instead, specify the convolution dimension
  // numbers when you create the instruction.
  void set_convolution_dimension_numbers(
      const ConvolutionDimensionNumbers& dnums) {
    convolution_dimension_numbers_ =
        MakeUnique<ConvolutionDimensionNumbers>(dnums);
  }

  FftType fft_type() const {
    CHECK_EQ(HloOpcode::kFft, opcode_);
    return fft_type_;
  }

  const std::vector<int64>& fft_length() const {
    CHECK_EQ(HloOpcode::kFft, opcode_);
    return fft_length_;
  }

  // Returns data on the dimension numbers used for a dot operation.
  const DotDimensionNumbers& dot_dimension_numbers() const {
    CHECK(dot_dimension_numbers_ != nullptr);
    return *dot_dimension_numbers_;
  }

  // Returns the dump string of the dot dimension numbers.
  string DotDimensionNumbersToString() const;

  const GatherDimensionNumbers& gather_dimension_numbers() const {
    CHECK(gather_dimension_numbers_ != nullptr);
    return *gather_dimension_numbers_;
  }

  tensorflow::gtl::ArraySlice<int64> gather_window_bounds() const {
    CHECK_EQ(opcode(), HloOpcode::kGather);
    return gather_window_bounds_;
  }

  // Returns the dump string of the gather dimension numbers.
  string GatherDimensionNumbersToString() const;

  // Returns the random distribution for this rng node.
  //
  // Precondition: opcode() == HloOpcode::kRng
  RandomDistribution random_distribution() const;

  // Clones the HLO instruction. The clone will have the same opcode, shape, and
  // operands. After creation the clone has no uses. "this" (the instruction
  // cloned from) is not changed. Suffix is the string to append to the name of
  // the instruction to form the name of the cloned instruction.
  // Ignores the control predecessors and successors of this HLO instruction.
  std::unique_ptr<HloInstruction> Clone(
      const string& suffix = "clone", HloCloneContext* context = nullptr) const;

  // Clones the HLO instruction as above but with new shape and operands.
  std::unique_ptr<HloInstruction> CloneWithNewOperands(
      const Shape& shape,
      tensorflow::gtl::ArraySlice<HloInstruction*> new_operands,
      HloCloneContext* context = nullptr) const;

  // Returns the computations this instruction directly calls (if any).
  const std::vector<HloComputation*>& called_computations() const {
    return called_computations_;
  }

  // Replaces all called computations based on a map function. This is needed
  // when we clone hlo_computations and want to let the instructions to point
  // to the newly cloned nodes.
  void ReplaceCalledComputations(
      std::function<HloComputation*(HloComputation*)> map_function) {
    for (int64 i = 0; i < called_computations_.size(); ++i) {
      called_computations_[i] = map_function(called_computations_[i]);
    }
  }

  // Clears out the called computations.
  //
  // This is, in particular, necessary when inlining function bodies into their
  // caller. If there were side-effecting operations in the called computations,
  // the call itself is considered side-effecting and thus cannot be removed. By
  // clearing out the computations, we reflect the fact that all side-effecting
  // properties have been reflected in the caller, and make the call HLO
  // removable.
  void ClearCalledComputations() { called_computations_.clear(); }

  // Returns true if this instruction performs an elementwise operation on
  // `operand_idx`-th operand. An instruction is elementwise on an operand iff,
  // after performing necessary implicit broadcast
  // (cs/IrArray::EmitArrayElementAddress), to compute the output at index
  // {i_0,i_1,...,i_n}, the only element required from the operand (if any) is
  // the element at {i_0,i_1,...,i_n}.
  //
  // Note on performance: when this instruction is kFusion, this method, in the
  // worst case, scans all fused instructions. We could speed this up by
  // caching.
  bool IsElementwiseOnOperand(int64 operand_idx) const;

  // Returns true if this instruction is elementwise on all its operands.
  bool IsElementwise() const;

  // Returns true if this elementwise instruction implicitly broadcasts operand
  // `operand_idx`.
  //
  // Precondition: this instruction should be an elementwise operation.
  bool ImplicitlyBroadcastsOperand(int64 operand_idx) const;

  // Returns true if this instruction is binary and elementwise.
  bool IsElementwiseBinary() const;

  // Returns whether this instruction may reuse elements of its `i`th operand.
  bool ReusesOperandElements(int64 i) const {
    return OperandElementUse(i) == UseKind::kReuse;
  }

  // Returns the indices that the given operand appear in the operand list of
  // this instruction. Note that an instruction can use the same operand
  // multiple times.
  std::vector<int64> OperandIndices(const HloInstruction* operand) const;

  // Convenience helper for ShapeUtil::InsertedOrDeleted1SizedDimensions. If
  // this reshape merely inserts or deletes 1-sized dimensions, return the input
  // indices of the deleted dimensions and the output indices of the inserted
  // dimensions.
  //
  // Precondition: this op must be a reshape.
  std::tuple<bool, std::vector<int64>, std::vector<int64>>
  ReshapeMerelyInsertsOrDeletes1SizedDimensions() const;

  // Gets/sets the string identifier for this instruction.
  const string& name() const { return name_; }
  void set_name(tensorflow::StringPiece name) { name_ = std::string(name); }

  // Use the given NameUniquer to select a unique name for the instruction based
  // on the instruction's existing name.
  void UniquifyName(NameUniquer* name_uniquer);

  // Set the unique id for this instruction to "id"
  void SetUniqueId(int id) {
    CHECK_EQ(unique_id_, -1);  // Should not be assigned already
    CHECK_GE(id, 0);
    unique_id_ = id;
  }

  // Return the unique ID assigned to this node via SetUniqueId (or -1
  // if no id has been assigned yet).
  int unique_id() const { return unique_id_; }

  // Returns the backend-specific configuration for how a backend should compile
  // this HLO. The meaning of the field is backend specific. Not for use before
  // or during general HLO optimization, since HLO optimizations do not preserve
  // this field and they cannot interpret it due to its meaning being backend
  // specific.
  //
  // ConfigProto should be a protobuf Message type.
  template <typename ConfigProto>
  StatusOr<ConfigProto> backend_config() const {
    ConfigProto proto;
    TF_RETURN_IF_ERROR(GetBackendConfigInternal(&proto));
    return std::move(proto);
  }
  Status set_backend_config(const tensorflow::protobuf::Message& proto);

  // Getter/setter for raw JSON-encoded backend config.  Prefer the
  // functions above that deal in proto Messages where possible.
  const string& raw_backend_config_string() const { return backend_config_; }
  void set_raw_backend_config_string(string config_str) {
    backend_config_ = std::move(config_str);
  }

  // Returns a string representation of a proto in the format used by
  // raw_backend_config_string.
  //
  // This is morally equivalent to:
  //
  //   HloInstruction instr;
  //   TF_RETURN_IF_ERROR(instr.set_backend_config(proto));
  //   return instr.raw_backend_config_string();
  //
  static StatusOr<string> BackendConfigToRawString(
      const tensorflow::protobuf::Message& proto);

  // Sets the debug metadata for this instruction.
  void set_metadata(const OpMetadata& metadata) { metadata_ = metadata; }
  const OpMetadata& metadata() const { return metadata_; }

  // Set/get the computation containing this instruction. set_parent should only
  // be called by HloComputation methods which add/remove instructions to
  // computations.
  void set_parent(HloComputation* computation) { parent_ = computation; }
  const HloComputation* parent() const { return parent_; }
  HloComputation* parent() { return parent_; }

  // Returns the module for this instruction.
  HloModule* GetModule() const;

  // Returns whether we could assign input and output layouts to this
  // instruction to make it a bitcast.
  bool CouldBeBitcast() const;

  // Get/Set the number of partitions per outer dimension (in order, starting
  // with outer-most dimension first). Currently used by the parallel cpu
  // backend to partition HLOs into parallel tasks.
  //
  // TODO(b/62783254) Replace these methods with a more general way to
  // annotate HLOs with backend-specific information.
  const std::vector<int64>& outer_dimension_partitions() const {
    return outer_dimension_partitions_;
  }
  void set_outer_dimension_partitions(
      const std::vector<int64>& outer_dimension_partitions);

  // Change the layout for an Constant Hlo instruction to match new_layout.  For
  // tuple shaped constants shape_index is the path to the internal array
  // subshape whose layout needs to be changed.
  void RelayoutConstant(const Layout& new_layout,
                        const ShapeIndex& shape_index = {});

 protected:
  // Internal constructor for a given opcode/shape, other fields must be filled
  // by factory methods.
  HloInstruction(HloOpcode opcode, const Shape& shape);

  // Appends operand to the list of operands and adds this instruction as a user
  // of the operand.
  void AppendOperand(HloInstruction* operand);

 private:
  // Implementation for non-common logic of CloneWithNewOperands.
  virtual std::unique_ptr<HloInstruction> CloneWithNewOperandsImpl(
      const Shape& shape,
      tensorflow::gtl::ArraySlice<HloInstruction*> new_operands,
      HloCloneContext* context) const {
    // TODO(b/80131774): This should be pure virtual.
    LOG(FATAL) << "Unimplemented method.";
  }
  // Prints an instruction to a string.
  //
  // The canonical string representation needs to name operands and instruction
  // names in a consistent way. This is implemented through the
  // canonical_name_map.
  string ToStringWithCanonicalNameMap(
      const HloPrintOptions& options,
      CanonicalNameMap* canonical_name_map) const;

  // Prints an operand to a string.
  string OperandsToStringWithCanonicalNameMap(
      const HloPrintOptions& options,
      CanonicalNameMap* canonical_name_map) const;

  // Allow HloInstruction to access the ToStringWithCanonicalNameMap() and
  // OperandsToStringWithCanonicalNameMap() functions.
  friend class HloComputation;

  enum class UseKind { kNoUse, kReuse, kUsePermutingElements, kUse };

  // Helper class for computing OperandElementUse for kFusion.
  class FusionReusesParamElements;

  // See comments on Identical().
  virtual bool IdenticalSlowPath(
      const HloInstruction& other,
      const std::function<bool(const HloComputation*, const HloComputation*)>&
          eq_computations) const;

  // Creates an n-ary elementwise operation.
  static std::unique_ptr<HloInstruction> CreateNary(
      const Shape& shape, HloOpcode opcode,
      tensorflow::gtl::ArraySlice<HloInstruction*> operands);

  // Adds a user for this instruction.
  void AddUser(HloInstruction* user);

  // Removes a user for this instruction.
  void RemoveUser(HloInstruction* user);

  // Fuses the given instruction into this fusion instruction. When add_output
  // is false (which is the default), instruction_to_fuse is cloned and the
  // clone is placed in the fusion instruction. instruction_to_fuse is
  // unchanged.
  //
  // When add_output is true, a clone of the instruction_to_fuse will be part
  // of the output of fusion instructions. The users of instruction_to_fuse
  // will be redirected to this fusion instructions. instruction_to_fuse will
  // be removed from its parent computation.
  //
  // Precondition: this->opcode() == HloOpcode::kFusion
  HloInstruction* FuseInstructionInternal(HloInstruction* instruction_to_fuse,
                                          bool add_output = false);

  // Clones the given instruction_to_fuse and insert the clone into this fusion
  // instruction. If add_output is true, a clone of instruction_to_fuse will
  // be in the output of the this fusion instruction (part of the tuple of the
  // fusion root).
  //
  // Precondition: opcode() == HloOpcode::kFusion
  HloInstruction* CloneAndFuseInternal(HloInstruction* instruction_to_fuse,
                                       bool add_output = false);

  // Clones a fusion instruction with a new shape and operands.
  std::unique_ptr<HloInstruction> CloneFusionWithNewOperands(
      const Shape& shape, tensorflow::gtl::ArraySlice<HloInstruction*> operands,
      HloCloneContext* context = nullptr) const;

  // Returns true if this instruction can legally have the dimensions field
  // set. Used for checking precondition of dimensions field accessors.
  bool CanHaveDimensionsField() const;

  // Returns how this instruction uses elements of its `i`th operand.
  UseKind OperandElementUse(int64 i) const;

  // Helper for implementing backend_config().  Parses backend_config_ into the
  // given proto.
  Status GetBackendConfigInternal(tensorflow::protobuf::Message* proto) const;

  int unique_id_;  // Unique to this HloInstruction within a HloModule

  // Opcode for this instruction.
  HloOpcode opcode_;

  // Instruction operands.
  InstructionVector operands_;

  // The set of control predecessors of this instruction.
  std::vector<HloInstruction*> control_predecessors_;

  // The users of this instruction. Users are HLOs where this instruction is an
  // operand. The vector users_ and the set user_set_ contain identical
  // members. The set enables fast membership testing and the vector enables
  // fast, stable iteration.
  std::vector<HloInstruction*> users_;
  std::unordered_set<const HloInstruction*> user_set_;

  // The set of control successors of this instruction.
  std::vector<HloInstruction*> control_successors_;

  // The computation in which this instruction is contained.
  HloComputation* parent_ = nullptr;

  // Shape of outfeed request.
  Shape outfeed_shape_;

  // Result shape of this instruction.
  Shape shape_;

  // Literal, only present for kConstant.
  std::unique_ptr<Literal> literal_;

  // Constant index, only present for kGetTupleElement.
  int64 tuple_index_ = -1;

  // Dimensions present for some operations that require reshaping or
  // broadcasting, including Reshape, Reduce, ReduceWindow, and Reverse.
  std::vector<int64> dimensions_;

  // Describes the window in a windowed operation such as convolution.
  std::unique_ptr<Window> window_;

  // Describes the dimension numbers used for a convolution.
  std::unique_ptr<ConvolutionDimensionNumbers> convolution_dimension_numbers_;

  // Describes the dimension numbers used for a dot.
  std::unique_ptr<DotDimensionNumbers> dot_dimension_numbers_;

  std::unique_ptr<GatherDimensionNumbers> gather_dimension_numbers_;
  std::vector<int64> gather_window_bounds_;

  // Describes FFT type for an FFT instruction.
  FftType fft_type_ = FftType::FFT;

  // Indicates the FFT length for an FFT instruction.
  std::vector<int64> fft_length_;

  // Describes the [begin, end) index range for a slice.
  std::vector<int64> slice_starts_;
  std::vector<int64> slice_limits_;
  std::vector<int64> slice_strides_;

  // Describes whether the slice can be lowered to an offset into the operand.
  bool is_in_place_slice_ = false;

  // The bit sizes for a reduce-precision operation.
  int32 exponent_bits_ = 0;
  int32 mantissa_bits_ = 0;

  // Describes the [start, start + size) range size for a dynamic slice
  // ('start' is specified dynamically in the second operand of the operation).
  std::vector<int64> dynamic_slice_sizes_;

  // The padding configuration that describes the edge padding and interior
  // padding of this pad instruction. Only set for pad instructions.
  std::unique_ptr<PaddingConfig> padding_config_;

  // The type of the fusion. Used by kFusion only.
  FusionKind fusion_kind_;

  // The sharding, if one exists.
  std::unique_ptr<HloSharding> sharding_;

  // Fields used by the kDomain instruction.
  std::unique_ptr<DomainMetadata> operand_side_metadata_;
  std::unique_ptr<DomainMetadata> user_side_metadata_;

  // For parameter instructions this field holds the parameter number.
  int64 parameter_number_ = 0;

  // Name of a global symbol to call, only present for kCustomCall.
  string custom_call_target_;

  // Name to use for host send/recv channels, only present for kHostCompute.
  string channel_name_;

  // Estimate of the duration of a host computation in nanoseconds.
  int64 cost_estimate_ns_ = 0;

  // Computations called by this instruction.
  std::vector<HloComputation*> called_computations_;

  // Indices of computations in called_computations_ for instructions which call
  // multiple computations.
  enum {
    // kWhile computations.
    kBodyComputationIndex = 0,
    kConditionComputationIndex = 1,

    // kSelectAndScatter computations.
    kSelectComputationIndex = 0,
    kScatterComputationIndex = 1,

    // kConditional computations.
    kTrueComputationIndex = 0,
    kFalseComputationIndex = 1,
  };

  // Outfeed configuration information, only present for kOutfeed.
  string outfeed_config_;

  // A trace instruction that consumes this instruction.
  //
  // Invariant: if trace_instruction_ != nullptr, trace_instruction has this as
  // an operand.
  HloInstruction* trace_instruction_ = nullptr;

  // The distribution requested for random number generation.
  // Only present for kRng.
  RandomDistribution distribution_;

  // Represents a unique identifier for each Send/Recv instruction pair.
  // Only present for kSend or kRecv.
  int64 channel_id_ = -1;

  // The string representation of the infeed configuration.
  string infeed_config_;

  // The backend-specific configuration for how a backend should compile this
  // HLO. See the documentation on backend_config().
  string backend_config_;

  // String identifier for instruction.
  string name_;

  // Metadata for debugging.
  OpMetadata metadata_;

  // The number of partitions per outer dimension (listed in order from
  // outer-most dimension first).
  std::vector<int64> outer_dimension_partitions_;

  TF_DISALLOW_COPY_AND_ASSIGN(HloInstruction);
};

string ToString(HloInstruction::FusionKind kind);
StatusOr<HloInstruction::FusionKind> StringToFusionKind(
    const string& kind_name);

// Custom (de)stringification functions for protos that live inside
// HloInstruction.
string PaddingConfigToString(const PaddingConfig& padding);
string OpMetadataToString(const OpMetadata& metadata);
string RandomDistributionToString(const RandomDistribution& distribution);
string ConvolutionDimensionNumbersToString(
    const ConvolutionDimensionNumbers& dnums);

StatusOr<RandomDistribution> StringToRandomDistribution(const string& name);

std::ostream& operator<<(std::ostream& os, HloInstruction::FusionKind kind);

// Map classes that guarantee a deterministic iteration order when the key is
// an HloInstruction* or a const HloInstruction*.
// To make the iteration order over the map deterministic, the comparator
// should not be using the pointer values, but rather an intrinsic property of
// the hlo. Exception: null pointer values compare less than non-null.
//
// Note that this cannot be used for HLO instructions across multiple modules
// since the id of HLO instructions are only unique within each HLO module.
struct HloPtrComparator {
  bool operator()(const HloInstruction* const& lhs,
                  const HloInstruction* const& rhs) const {
    if (rhs == nullptr) {
      // Nothing compares less than nullptr.
      return false;
    }
    if (lhs == nullptr) {
      return true;
    }
    return lhs->unique_id() < rhs->unique_id();
  }
};

template <typename ValueT>
using HloInstructionMap = std::map<HloInstruction*, ValueT, HloPtrComparator>;

template <typename ValueT>
using ConstHloInstructionMap =
    std::map<const HloInstruction*, ValueT, HloPtrComparator>;

using HloInstructionSet = std::set<HloInstruction*, HloPtrComparator>;
using ConstHloInstructionSet =
    std::set<const HloInstruction*, HloPtrComparator>;

}  // namespace xla

#endif  // TENSORFLOW_COMPILER_XLA_SERVICE_HLO_INSTRUCTION_H_


text:
print ("Hi, enjoy hacking with Lua");
function timer200()
  calltest("test1", "test2");
end;


text:
// Copyright 2009 the Sputnik authors.  All rights reserved.
/**
 * The Object.prototype.propertyIsEnumerable.length property has the attribute DontEnum
 *
 * @path ch15/15.2/15.2.4/15.2.4.7/S15.2.4.7_A8.js
 * @description Checking if enumerating the Object.prototype.propertyIsEnumerable.length property fails
 */

//CHECK#0
if (!(Object.prototype.propertyIsEnumerable.hasOwnProperty('length'))) {
  $FAIL('#0: the Object.prototype.propertyIsEnumerable has length property');
}

// CHECK#1
if (Object.prototype.propertyIsEnumerable.propertyIsEnumerable('length')) {
  $ERROR('#1: the Object.prototype.propertyIsEnumerable.length property has the attributes DontEnum');
}

// CHECK#2
for (p in Object.prototype.propertyIsEnumerable){
  if (p==="length")
        $ERROR('#2: the Object.prototype.propertyIsEnumerable.length property has the attributes DontEnum');
}
//


text:
(function (factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['jquery', 'datatables.net-bs', 'datatables.net-searchPanes'], function ($) {
            return factory($, window, document);
        });
    }
    else if (typeof exports === 'object') {
        // CommonJS
        module.exports = function (root, $) {
            if (!root) {
                root = window;
            }
            if (!$ || !$.fn.dataTable) {
                $ = require('datatables.net-bs')(root, $).$;
            }
            if (!$.fn.dataTable.searchPanes) {
                require('datatables.net-searchPanes')(root, $);
            }
            return factory($, root, root.document);
        };
    }
    else {
        // Browser
        factory(jQuery, window, document);
    }
}(function ($, window, document) {
    'use strict';
    var DataTable = $.fn.dataTable;
    $.extend(true, DataTable.SearchPane.classes, {
        buttonGroup: 'btn-group',
        disabledButton: 'disabled',
        dull: 'disabled',
        narrow: 'col narrow',
        narrowSub: 'row',
        pane: {
            container: 'table'
        },
        paneButton: 'btn btn-light',
        pill: 'badge badge-pill badge-light pill',
        search: 'col-sm form-control search',
        searchCont: 'input-group dtsp-searchCont',
        searchLabelCont: 'input-group-btn',
        show: 'col',
        subRow1: 'dtsp-subRow1 text-right',
        subRow2: 'dtsp-subRow2 text-right',
        table: 'table table-condensed',
        topRow: 'dtsp-topRow'
    });
    $.extend(true, DataTable.SearchPanes.classes, {
        clearAll: 'dtsp-clearAll col-1 btn btn-light',
        container: 'dtsp-searchPanes row',
        panes: 'dtsp-panesContainer',
        title: 'dtsp-title col-10',
        titleRow: 'row'
    });
    return DataTable.searchPanes;
}));


text:
 Members Page

Just an example page which shows all members of the workspace


text:
<?php

/**
 * image actions.
 *
 * @package    codelovely
 * @subpackage image
 * @author     Sanjeevan Ambalavanar
 * @version    SVN: $Id: actions.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class imageActions extends sfActions
{
  public function executeCropSnapshot(sfWebRequest $request)
  {
    $this->article = Doctrine::getTable('Article')->find($request->getParameter('articleid'));
    $this->file = $this->article->getSnapshot();

    if (!$this->file){
      $this->forward404("Snapshot not found");
    }

    $image = new sfImage($this->file->getLocation(), $this->file->getMimeType());
    $this->imgw = $image->getWidth();
    $this->imgh = $image->getHeight();

    if ($request->isMethod('post')){
      $left = $request->getParameter('x');
      $top = $request->getParameter('y');
      $image->crop($left, $top, 400, 300);
      $image->save();

      $this->file->setHash(sha1_file($this->file->getLocation()));
      $this->file->save();

      $this->getUser()->setFlash('notice', 'Image has been cropped');
      $this->redirect($this->article->getViewUrl());
    }

    /*
    $image = new sfImage($this->file->getLocation(), $this->file->getMimeType());
    $max_width = 800;

    if ($image->getWidth() > $max_width){
      $thumb = new sfThumbnail($max_width, $max_width, true, true, 100);
      $thumb->loadFile($this->file->getLocation());
      $thumb->save($this->file->getLocation(), 'image/png');

      $this->file->setHash(sha1_file($this->file->getLocation()));
      $this->file->save();
    }
    */
  }
}


text:
'use strict';

require( 'jasmine' );

var oldConsoleLog = console.log;

var BrjsvctViewModel = require( 'dashboard/brjsvct/BrjsvctViewModel' );

describe('Brjsvct Tests', function() {

	beforeEach(function() {
		console.log = jasmine.createSpy();
	});

	afterEach(function() {
		console.log = oldConsoleLog;
	});

	it( 'Should log hello on load', function() {
		new BrjsvctViewModel();
		expect(console.log).toHaveBeenCalledWith('Welcome to your new Blade.');
	});

});


text:
package com.querydsl.jpa.impl;

import java.util.List;
import java.util.Map;

import javax.persistence.Parameter;
import javax.persistence.Query;

import com.querydsl.core.types.ParamExpression;
import com.querydsl.core.types.ParamNotSetException;
import com.querydsl.core.types.dsl.Param;
import com.querydsl.core.util.MathUtils;

/**
 * JPAUtil provides static utility methods for JPA
 *
 * @author tiwe
 *
 */
public final class JPAUtil {

    private JPAUtil() { }

    public static void setConstants(Query query, List<Object> constants, Map<ParamExpression<?>, Object> params) {
        boolean hasParameters = !query.getParameters().isEmpty();

        for (int i = 0; i < constants.size(); i++) {
            Object val = constants.get(i);

            if (val instanceof Param) {
                Param<?> param = (Param<?>) val;
                val = params.get(val);
                if (val == null) {
                    throw new ParamNotSetException(param);
                }
            }

            if (hasParameters) {
                Parameter parameter = query.getParameter(i + 1);
                Class parameterType = parameter != null ? parameter.getParameterType() : null;
                if (parameterType != null && !parameterType.isInstance(val)) {
                    if (val instanceof Number && Number.class.isAssignableFrom(parameterType)) {
                        val = MathUtils.cast((Number) val, parameterType);
                    }
                }
            }

            query.setParameter(i + 1, val);
        }
    }

}


text:
require "sidekiq/api"

require "sidekiq/testing"
Sidekiq::Testing.disable!

Sidekiq.configure_server do |config|
  config.redis = { url: "redis://:password@127.0.0.1:6379/12" }
end

Sidekiq.configure_client do |config|
  config.redis = { url: "redis://:password@127.0.0.1:6379/12" }
end

module SidekiqJobsManager
  def setup
    ActiveJob::Base.queue_adapter = :sidekiq
    unless can_run?
      puts "Cannot run integration tests for sidekiq. To be able to run integration tests for sidekiq you need to install and start redis.\n"
      exit
    end
  end

  def clear_jobs
    Sidekiq::ScheduledSet.new.clear
    Sidekiq::Queue.new("integration_tests").clear
  end

  def start_workers
    continue_read, continue_write = IO.pipe
    death_read, death_write = IO.pipe

    @pid = fork do
      continue_read.close
      death_write.close

      # Sidekiq is not warning-clean :(
      $VERBOSE = false

      $stdin.reopen(File::NULL)
      $stdout.sync = true
      $stderr.sync = true

      logfile = Rails.root.join("log/sidekiq.log").to_s
      Sidekiq::Logging.initialize_logger(logfile)

      self_read, self_write = IO.pipe
      trap "TERM" do
        self_write.puts("TERM")
      end

      Thread.new do
        begin
          death_read.read
        rescue Exception
        end
        self_write.puts("TERM")
      end

      require "sidekiq/launcher"
      sidekiq = Sidekiq::Launcher.new(queues: ["integration_tests"],
                                       environment: "test",
                                       concurrency: 1,
                                       timeout: 1)
      Sidekiq.average_scheduled_poll_interval = 0.5
      Sidekiq.options[:poll_interval_average] = 1
      begin
        sidekiq.run
        continue_write.puts "started"
        while readable_io = IO.select([self_read])
          signal = readable_io.first[0].gets.strip
          raise Interrupt if signal == "TERM"
        end
      rescue Interrupt
      end

      sidekiq.stop
      exit!
    end
    continue_write.close
    death_read.close
    @worker_lifeline = death_write

    raise "Failed to start worker" unless continue_read.gets == "started\n"
  end

  def stop_workers
    if @pid
      Process.kill "TERM", @pid
      Process.wait @pid
    end
  end

  def can_run?
    begin
      Sidekiq.redis(&:info)
      Sidekiq.logger = nil
    rescue
      return false
    end
    true
  end
end


text:
/**
 * Created by cwcordell on 10/24/16.
 */
"use strict";
var Story = (function () {
    function Story(id, worldId, title, pro, choice1Text, choice1Rule, choice2Text, choice2Rule) {
        this.id = id;
        this.worldId = worldId;
        this.title = title;
        this.prologue = pro;
        this.choice1Text = choice1Text;
        this.choice1Rule = choice1Rule;
        this.choice2Text = choice2Text;
        this.choice2Rule = choice2Rule;
    }
    return Story;
}());
exports.Story = Story;
//# sourceMappingURL=Story.js.map