DPC++ Runtime
Runtime libraries for oneAPI DPC++
commands.hpp
Go to the documentation of this file.
1 //==-------------- commands.hpp - SYCL standard header file ----------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #pragma once
10 
11 #include <atomic>
12 #include <cstdint>
13 #include <deque>
14 #include <memory>
15 #include <optional>
16 #include <set>
17 #include <unordered_set>
18 #include <vector>
19 
20 #include <detail/accessor_impl.hpp>
21 #include <detail/event_impl.hpp>
23 #include <sycl/access/access.hpp>
24 #include <sycl/detail/cg.hpp>
25 
26 namespace sycl {
27 inline namespace _V1 {
28 namespace detail {
29 
30 #ifdef XPTI_ENABLE_INSTRUMENTATION
31 bool CurrentCodeLocationValid();
32 void emitInstrumentationGeneral(uint32_t StreamID, uint64_t InstanceID,
33  xpti_td *TraceEvent, uint16_t Type,
34  const char *Txt);
35 #endif
36 
37 class queue_impl;
38 class event_impl;
39 class context_impl;
40 class DispatchHostTask;
41 
42 using QueueImplPtr = std::shared_ptr<detail::queue_impl>;
43 using EventImplPtr = std::shared_ptr<detail::event_impl>;
44 using ContextImplPtr = std::shared_ptr<detail::context_impl>;
45 using StreamImplPtr = std::shared_ptr<detail::stream_impl>;
46 
47 class Command;
48 class AllocaCommand;
49 class AllocaCommandBase;
50 class ReleaseCommand;
51 class ExecCGCommand;
52 class EmptyCommand;
53 
55 
58  enum ResultT {
63  };
65  pi_int32 ErrCode = PI_SUCCESS)
66  : MResult(Result), MCmd(Cmd), MErrCode(ErrCode) {}
73 };
74 
76 struct DepDesc {
77  DepDesc(Command *DepCommand, const Requirement *Req,
78  AllocaCommandBase *AllocaCmd)
79  : MDepCommand(DepCommand), MDepRequirement(Req), MAllocaCmd(AllocaCmd) {}
80 
81  friend bool operator<(const DepDesc &Lhs, const DepDesc &Rhs) {
82  return std::tie(Lhs.MDepRequirement, Lhs.MDepCommand) <
84  }
85 
87  Command *MDepCommand = nullptr;
89  const Requirement *MDepRequirement = nullptr;
93 };
94 
102 class Command {
103 public:
104  enum CommandType {
117  };
118 
119  Command(CommandType Type, QueueImplPtr Queue,
120  sycl::detail::pi::PiExtCommandBuffer CommandBuffer = nullptr,
121  const std::vector<sycl::detail::pi::PiExtSyncPoint> &SyncPoints = {});
122 
126  [[nodiscard]] Command *addDep(DepDesc NewDep,
127  std::vector<Command *> &ToCleanUp);
128 
132  [[nodiscard]] Command *addDep(EventImplPtr Event,
133  std::vector<Command *> &ToCleanUp);
134 
135  void addUser(Command *NewUser) { MUsers.insert(NewUser); }
136 
138  CommandType getType() const { return MType; }
139 
147  virtual bool enqueue(EnqueueResultT &EnqueueResult, BlockingT Blocking,
148  std::vector<Command *> &ToCleanUp);
149 
150  bool isFinished();
151 
152  bool isSuccessfullyEnqueued() const {
154  }
155 
156  // Shows that command could not be enqueued, now it may be true for empty task
157  // only
158  bool isEnqueueBlocked() const {
160  }
161  // Shows that command could be enqueued, but is blocking enqueue of all
162  // commands depending on it. Regular usage - host task.
163  bool isBlocking() const { return isHostTask() && !MEvent->isCompleted(); }
164 
165  void addBlockedUserUnique(const EventImplPtr &NewUser) {
166  if (std::find(MBlockedUsers.begin(), MBlockedUsers.end(), NewUser) !=
167  MBlockedUsers.end())
168  return;
169  MBlockedUsers.push_back(NewUser);
170  }
171 
172  const QueueImplPtr &getQueue() const { return MQueue; }
173 
174  const EventImplPtr &getEvent() const { return MEvent; }
175 
176  // Methods needed to support SYCL instrumentation
177 
181  virtual void emitInstrumentationData() = 0;
184  void resolveReleaseDependencies(std::set<Command *> &list);
187  Command *Cmd, void *ObjAddr, bool IsCommand,
188  std::optional<access::mode> AccMode = std::nullopt);
191  sycl::detail::pi::PiEvent &EventAddr);
198  uint64_t makeTraceEventProlog(void *MAddress);
201  void makeTraceEventEpilog();
203  void emitInstrumentation(uint16_t Type, const char *Txt = nullptr);
204 
205  // End Methods needed to support SYCL instrumentation
206 
207  virtual void printDot(std::ostream &Stream) const = 0;
208 
209  virtual const Requirement *getRequirement() const {
210  assert(false && "Internal Error. The command has no stored requirement");
211  return nullptr;
212  }
213 
214  virtual ~Command() { MEvent->cleanDepEventsThroughOneLevel(); }
215 
216  const char *getBlockReason() const;
217 
220  virtual const ContextImplPtr &getWorkerContext() const;
221 
224  const QueueImplPtr &getWorkerQueue() const;
225 
227  virtual bool producesPiEvent() const;
228 
230  virtual bool supportsPostEnqueueCleanup() const;
231 
233  virtual bool readyForCleanup() const;
234 
237  std::vector<sycl::detail::pi::PiEvent>
238  getPiEvents(const std::vector<EventImplPtr> &EventImpls) const;
242  std::vector<sycl::detail::pi::PiEvent>
243  getPiEventsBlocking(const std::vector<EventImplPtr> &EventImpls) const;
244 
245  bool isHostTask() const;
246 
247 protected:
251 
254  std::vector<EventImplPtr> &MPreparedDepsEvents;
255  std::vector<EventImplPtr> &MPreparedHostDepsEvents;
256 
257  void waitForEvents(QueueImplPtr Queue, std::vector<EventImplPtr> &RawEvents,
259 
260  void waitForPreparedHostEvents() const;
261 
273  [[nodiscard]] Command *processDepEvent(EventImplPtr DepEvent,
274  const DepDesc &Dep,
275  std::vector<Command *> &ToCleanUp);
276 
278  virtual pi_int32 enqueueImp() = 0;
279 
283  std::mutex MEnqueueMtx;
284 
285  friend class DispatchHostTask;
286 
287 public:
288  const std::vector<EventImplPtr> &getPreparedHostDepsEvents() const {
290  }
291 
292  const std::vector<EventImplPtr> &getPreparedDepsEvents() const {
293  return MPreparedDepsEvents;
294  }
295 
296  // XPTI instrumentation. Copy code location details to the internal struct.
297  // Memory is allocated in this method and released in destructor.
299 
306  MPreparedDepsEvents.clear();
307  MPreparedHostDepsEvents.clear();
308  MDeps.clear();
309  }
310 
312  std::vector<DepDesc> MDeps;
314  std::unordered_set<Command *> MUsers;
316  bool MIsBlockable = false;
318  unsigned MLeafCounter = 0;
319 
320  struct Marks {
322  bool MVisited = false;
324  bool MToBeDeleted = false;
325  };
328 
329  enum class BlockReason : int { HostAccessor = 0, HostTask };
330 
331  // Only have reasonable value while MIsBlockable is true
333 
335  std::atomic<EnqueueResultT::ResultT> MEnqueueStatus;
336 
337  // All member variables defined here are needed for the SYCL instrumentation
338  // layer. Do not guard these variables below with XPTI_ENABLE_INSTRUMENTATION
339  // to ensure we have the same object layout when the macro in the library and
340  // SYCL app are not the same.
341 
343  void *MTraceEvent = nullptr;
347  int32_t MStreamID = -1;
350  void *MAddress = nullptr;
352  std::string MAddressString;
354  std::string MCommandNodeType;
356  std::string MCommandName;
360  bool MFirstInstance = false;
362  uint64_t MInstanceID = 0;
369  std::string MSubmissionFileName;
371 
372  // This flag allows to control whether host event should be set complete
373  // after successfull enqueue of command. Event is considered as host event if
374  // either it's is_host() return true or there is no backend representation
375  // of event (i.e. getHandleRef() return reference to nullptr value).
376  // By default the flag is set to true due to most of host operations are
377  // synchronous. The only asynchronous operation currently is host-task.
379 
383  bool MMarkedForCleanup = false;
384 
390  std::vector<EventImplPtr> MBlockedUsers;
391  std::mutex MBlockedUsersMutex;
392 
393 protected:
396  return MCommandBuffer;
397  }
398 
403  std::vector<sycl::detail::pi::PiExtSyncPoint> MSyncPointDeps;
404 };
405 
408 class EmptyCommand : public Command {
409 public:
410  EmptyCommand(QueueImplPtr Queue);
411 
412  void printDot(std::ostream &Stream) const final;
413  const Requirement *getRequirement() const final { return &MRequirements[0]; }
414  void addRequirement(Command *DepCmd, AllocaCommandBase *AllocaCmd,
415  const Requirement *Req);
416 
417  void emitInstrumentationData() override;
418 
419  bool producesPiEvent() const final;
420 
421 private:
422  pi_int32 enqueueImp() final;
423 
424  // Employing deque here as it allows to push_back/emplace_back without
425  // invalidation of pointer or reference to stored data item regardless of
426  // iterator invalidation.
427  std::deque<Requirement> MRequirements;
428 };
429 
432 class ReleaseCommand : public Command {
433 public:
434  ReleaseCommand(QueueImplPtr Queue, AllocaCommandBase *AllocaCmd);
435 
436  void printDot(std::ostream &Stream) const final;
437  void emitInstrumentationData() override;
438  bool producesPiEvent() const final;
439  bool supportsPostEnqueueCleanup() const final;
440  bool readyForCleanup() const final;
441 
442 private:
443  pi_int32 enqueueImp() final;
444 
446  AllocaCommandBase *MAllocaCmd = nullptr;
447 };
448 
450 class AllocaCommandBase : public Command {
451 public:
453  AllocaCommandBase *LinkedAllocaCmd, bool IsConst);
454 
455  ReleaseCommand *getReleaseCmd() { return &MReleaseCmd; }
456 
457  SYCLMemObjI *getSYCLMemObj() const { return MRequirement.MSYCLMemObj; }
458 
459  virtual void *getMemAllocation() const = 0;
460 
461  const Requirement *getRequirement() const final { return &MRequirement; }
462 
463  void emitInstrumentationData() override;
464 
465  bool producesPiEvent() const final;
466 
467  bool supportsPostEnqueueCleanup() const final;
468 
469  bool readyForCleanup() const final;
470 
471  void *MMemAllocation = nullptr;
472 
478  AllocaCommandBase *MLinkedAllocaCmd = nullptr;
480  bool MIsActive = true;
481 
484  bool MIsLeaderAlloca = true;
485  // Indicates that the data in this allocation must not be modified
486  bool MIsConst = false;
487 
488 protected:
489  Requirement MRequirement;
490  ReleaseCommand MReleaseCmd;
491 };
492 
496 public:
498  bool InitFromUserData = true,
499  AllocaCommandBase *LinkedAllocaCmd = nullptr,
500  bool IsConst = false);
501 
502  void *getMemAllocation() const final { return MMemAllocation; }
503  void printDot(std::ostream &Stream) const final;
504  void emitInstrumentationData() override;
505 
506 private:
507  pi_int32 enqueueImp() final;
508 
511  bool MInitFromUserData = false;
512 };
513 
516 public:
518  AllocaCommandBase *ParentAlloca,
519  std::vector<Command *> &ToEnqueue,
520  std::vector<Command *> &ToCleanUp);
521 
522  void *getMemAllocation() const final;
523  void printDot(std::ostream &Stream) const final;
524  AllocaCommandBase *getParentAlloca() { return MParentAlloca; }
525  void emitInstrumentationData() override;
526 
527 private:
528  pi_int32 enqueueImp() final;
529 
530  AllocaCommandBase *MParentAlloca = nullptr;
531 };
532 
534 class MapMemObject : public Command {
535 public:
536  MapMemObject(AllocaCommandBase *SrcAllocaCmd, Requirement Req, void **DstPtr,
537  QueueImplPtr Queue, access::mode MapMode);
538 
539  void printDot(std::ostream &Stream) const final;
540  const Requirement *getRequirement() const final { return &MSrcReq; }
541  void emitInstrumentationData() override;
542 
543 private:
544  pi_int32 enqueueImp() final;
545 
546  AllocaCommandBase *MSrcAllocaCmd = nullptr;
547  Requirement MSrcReq;
548  void **MDstPtr = nullptr;
549  access::mode MMapMode;
550 };
551 
553 class UnMapMemObject : public Command {
554 public:
555  UnMapMemObject(AllocaCommandBase *DstAllocaCmd, Requirement Req,
556  void **SrcPtr, QueueImplPtr Queue);
557 
558  void printDot(std::ostream &Stream) const final;
559  const Requirement *getRequirement() const final { return &MDstReq; }
560  void emitInstrumentationData() override;
561  bool producesPiEvent() const final;
562 
563 private:
564  pi_int32 enqueueImp() final;
565 
566  AllocaCommandBase *MDstAllocaCmd = nullptr;
567  Requirement MDstReq;
568  void **MSrcPtr = nullptr;
569 };
570 
573 class MemCpyCommand : public Command {
574 public:
575  MemCpyCommand(Requirement SrcReq, AllocaCommandBase *SrcAllocaCmd,
576  Requirement DstReq, AllocaCommandBase *DstAllocaCmd,
577  QueueImplPtr SrcQueue, QueueImplPtr DstQueue);
578 
579  void printDot(std::ostream &Stream) const final;
580  const Requirement *getRequirement() const final { return &MDstReq; }
581  void emitInstrumentationData() final;
582  const ContextImplPtr &getWorkerContext() const final;
583  bool producesPiEvent() const final;
584 
585 private:
586  pi_int32 enqueueImp() final;
587 
588  QueueImplPtr MSrcQueue;
589  Requirement MSrcReq;
590  AllocaCommandBase *MSrcAllocaCmd = nullptr;
591  Requirement MDstReq;
592  AllocaCommandBase *MDstAllocaCmd = nullptr;
593 };
594 
597 class MemCpyCommandHost : public Command {
598 public:
599  MemCpyCommandHost(Requirement SrcReq, AllocaCommandBase *SrcAllocaCmd,
600  Requirement DstReq, void **DstPtr, QueueImplPtr SrcQueue,
601  QueueImplPtr DstQueue);
602 
603  void printDot(std::ostream &Stream) const final;
604  const Requirement *getRequirement() const final { return &MDstReq; }
605  void emitInstrumentationData() final;
606  const ContextImplPtr &getWorkerContext() const final;
607 
608 private:
609  pi_int32 enqueueImp() final;
610 
611  QueueImplPtr MSrcQueue;
612  Requirement MSrcReq;
613  AllocaCommandBase *MSrcAllocaCmd = nullptr;
614  Requirement MDstReq;
615  void **MDstPtr = nullptr;
616 };
617 
618 pi_int32
619 enqueueReadWriteHostPipe(const QueueImplPtr &Queue, const std::string &PipeName,
620  bool blocking, void *ptr, size_t size,
621  std::vector<sycl::detail::pi::PiEvent> &RawEvents,
622  const detail::EventImplPtr &OutEventImpl, bool read);
623 
625  const QueueImplPtr &Queue, NDRDescT &NDRDesc, std::vector<ArgDesc> &Args,
626  const std::shared_ptr<detail::kernel_bundle_impl> &KernelBundleImplPtr,
627  const std::shared_ptr<detail::kernel_impl> &MSyclKernel,
628  const std::string &KernelName,
629  std::vector<sycl::detail::pi::PiEvent> &RawEvents,
630  const detail::EventImplPtr &Event,
631  const std::function<void *(Requirement *Req)> &getMemAllocationFunc,
632  sycl::detail::pi::PiKernelCacheConfig KernelCacheConfig);
633 
634 class KernelFusionCommand;
635 
638 class ExecCGCommand : public Command {
639 public:
641  std::unique_ptr<detail::CG> CommandGroup, QueueImplPtr Queue,
642  sycl::detail::pi::PiExtCommandBuffer CommandBuffer = nullptr,
643  const std::vector<sycl::detail::pi::PiExtSyncPoint> &Dependencies = {});
644 
645  std::vector<std::shared_ptr<const void>> getAuxiliaryResources() const;
646 
647  void clearAuxiliaryResources();
648 
649  void printDot(std::ostream &Stream) const final;
650  void emitInstrumentationData() final;
651 
652  detail::CG &getCG() const { return *MCommandGroup; }
653 
654  // MEmptyCmd is only employed if this command refers to host-task.
655  // The mechanism of lookup for single EmptyCommand amongst users of
656  // host-task-representing command is unreliable. This unreliability roots in
657  // the cleanup process.
658  EmptyCommand *MEmptyCmd = nullptr;
659 
660  // MFusionCommand is employed to mark a CG command as part of a kernel fusion
661  // and allows to refer back to the corresponding KernelFusionCommand if
662  // necessary.
663  KernelFusionCommand *MFusionCmd = nullptr;
664 
665  bool producesPiEvent() const final;
666 
667  bool supportsPostEnqueueCleanup() const final;
668 
669  bool readyForCleanup() const final;
670 
671 private:
672  pi_int32 enqueueImp() final;
673  pi_int32 enqueueImpCommandBuffer();
674  pi_int32 enqueueImpQueue();
675 
676  AllocaCommandBase *getAllocaForReq(Requirement *Req);
677 
678  std::unique_ptr<detail::CG> MCommandGroup;
679 
680  friend class Command;
681 };
682 
683 // For XPTI instrumentation only.
684 // Method used to emit data in cases when we do not create node in graph.
685 // Very close to ExecCGCommand::emitInstrumentationData content.
686 #ifdef XPTI_ENABLE_INSTRUMENTATION
687 std::pair<xpti_td *, uint64_t> emitKernelInstrumentationData(
688  int32_t StreamID, const std::shared_ptr<detail::kernel_impl> &SyclKernel,
689  const detail::code_location &CodeLoc, const std::string &SyclKernelName,
690  const QueueImplPtr &Queue, const NDRDescT &NDRDesc,
691  const std::shared_ptr<detail::kernel_bundle_impl> &KernelBundleImplPtr,
692  std::vector<ArgDesc> &CGArgs);
693 #endif
694 
696 public:
698  AllocaCommandBase *SrcAllocaCmd, void **DstPtr);
699 
700  void printDot(std::ostream &Stream) const final;
701  const Requirement *getRequirement() const final { return &MDstReq; }
702  void emitInstrumentationData() final;
703 
704 private:
705  pi_int32 enqueueImp() final;
706 
707  AllocaCommandBase *MSrcAllocaCmd = nullptr;
708  Requirement MDstReq;
709  void **MDstPtr = nullptr;
710 };
711 
714 class KernelFusionCommand : public Command {
715 public:
716  enum class FusionStatus { ACTIVE, CANCELLED, COMPLETE, DELETED };
717 
718  explicit KernelFusionCommand(QueueImplPtr Queue);
719 
720  void printDot(std::ostream &Stream) const final;
721  void emitInstrumentationData() final;
722  bool producesPiEvent() const final;
723 
724  std::vector<Command *> &auxiliaryCommands();
725 
726  void addToFusionList(ExecCGCommand *Kernel);
727 
728  std::vector<ExecCGCommand *> &getFusionList();
729 
733  void setFusionStatus(FusionStatus Status);
734 
738  void resetQueue();
739 
740  bool isActive() const { return MStatus == FusionStatus::ACTIVE; }
741 
742  bool readyForDeletion() const { return MStatus == FusionStatus::DELETED; }
743 
744 private:
745  pi_int32 enqueueImp() final;
746 
747  std::vector<ExecCGCommand *> MFusionList;
748 
749  std::vector<Command *> MAuxiliaryCommands;
750 
751  FusionStatus MStatus;
752 };
753 
754 // Enqueues a given kernel to a PiExtCommandBuffer
756  context Ctx, DeviceImplPtr DeviceImpl,
757  sycl::detail::pi::PiExtCommandBuffer CommandBuffer,
758  const CGExecKernel &CommandGroup,
759  std::vector<sycl::detail::pi::PiExtSyncPoint> &SyncPoints,
760  sycl::detail::pi::PiExtSyncPoint *OutSyncPoint,
761  const std::function<void *(Requirement *Req)> &getMemAllocationFunc);
762 
763 // Sets arguments for a given kernel and device based on the argument type.
764 // Refactored from SetKernelParamsAndLaunch to allow it to be used in the graphs
765 // extension.
766 void SetArgBasedOnType(
767  const detail::plugin &Plugin, sycl::detail::pi::PiKernel Kernel,
768  const std::shared_ptr<device_image_impl> &DeviceImageImpl,
769  const std::function<void *(Requirement *Req)> &getMemAllocationFunc,
770  const sycl::context &Context, bool IsHost, detail::ArgDesc &Arg,
771  size_t NextTrueIndex);
772 
774  const KernelArgMask *EliminatedArgMask, std::vector<ArgDesc> &Args,
775  std::function<void(detail::ArgDesc &Arg, int NextTrueIndex)> Func);
776 
778 
779 } // namespace detail
780 } // namespace _V1
781 } // namespace sycl
sycl::_V1::detail::Command::isHostTask
bool isHostTask() const
Definition: commands.cpp:297
sycl::_V1::detail::Command::copySubmissionCodeLocation
void copySubmissionCodeLocation()
Definition: commands.cpp:957
sycl::_V1::detail::EmptyCommand::getRequirement
const Requirement * getRequirement() const final
Definition: commands.hpp:413
sycl::_V1::detail::Command::MEvent
EventImplPtr MEvent
Definition: commands.hpp:249
sycl::_V1::detail::Command::MQueue
QueueImplPtr MQueue
Definition: commands.hpp:248
sycl::_V1::detail::Command
The Command class represents some action that needs to be performed on one or more memory objects.
Definition: commands.hpp:102
sycl::_V1::detail::EnqueueResultT::MResult
ResultT MResult
Indicates the result of enqueueing.
Definition: commands.hpp:68
sycl::_V1::detail::Command::readyForCleanup
virtual bool readyForCleanup() const
Returns true iff this command is ready to be submitted for cleanup.
Definition: commands.cpp:744
event_impl.hpp
sycl::_V1::detail::UnMapMemObject::getRequirement
const Requirement * getRequirement() const final
Definition: commands.hpp:559
sycl::_V1::detail::EmptyCommand::emitInstrumentationData
void emitInstrumentationData() override
Instrumentation method which emits telemetry data.
Definition: commands.cpp:1730
sycl::_V1::detail::Command::emitInstrumentationData
virtual void emitInstrumentationData()=0
Instrumentation method which emits telemetry data.
cg.hpp
sycl::_V1::access::mode
mode
Definition: access.hpp:34
sycl::_V1::detail::Command::MShouldCompleteEventIfPossible
bool MShouldCompleteEventIfPossible
Definition: commands.hpp:378
sycl::_V1::detail::Command::isSuccessfullyEnqueued
bool isSuccessfullyEnqueued() const
Definition: commands.hpp:152
sycl::_V1::detail::ContextImplPtr
std::shared_ptr< sycl::detail::context_impl > ContextImplPtr
Definition: event_impl.hpp:33
sycl::_V1::detail::Command::getPiEventsBlocking
std::vector< sycl::detail::pi::PiEvent > getPiEventsBlocking(const std::vector< EventImplPtr > &EventImpls) const
Collect PI events from EventImpls and filter out some of them in case of in order queue.
Definition: commands.cpp:260
sycl::_V1::detail::Command::getRequirement
virtual const Requirement * getRequirement() const
Definition: commands.hpp:209
sycl::_V1::detail::Command::resolveReleaseDependencies
void resolveReleaseDependencies(std::set< Command * > &list)
Looks at all the dependencies for the release command and enables instrumentation to report these dep...
Definition: commands.cpp:904
sycl::_V1::detail::Command::MMarks
Marks MMarks
Used for marking the node during graph traversal.
Definition: commands.hpp:327
sycl::_V1::detail::Command::MSubmissionFunctionName
std::string MSubmissionFunctionName
Definition: commands.hpp:370
sycl::_V1::detail::AccessorImplHost
Definition: accessor_impl.hpp:42
sycl::_V1::detail::Command::MTraceEventPrologComplete
bool MTraceEventPrologComplete
Flag to indicate if makeTraceEventProlog() has been run.
Definition: commands.hpp:358
sycl::_V1::detail::pi::PiKernelCacheConfig
::pi_kernel_cache_config PiKernelCacheConfig
Definition: pi.hpp:155
sycl::_V1::detail::Command::emitEnqueuedEventSignal
void emitEnqueuedEventSignal(sycl::detail::pi::PiEvent &PiEventAddr)
Creates a signal event with the enqueued kernel event handle.
Definition: commands.cpp:789
sycl::_V1::detail::Command::MInstanceID
uint64_t MInstanceID
Instance ID tracked for the command.
Definition: commands.hpp:362
sycl::_V1::detail::DeviceImplPtr
std::shared_ptr< device_impl > DeviceImplPtr
Definition: program_manager.hpp:65
sycl::_V1::detail::MemCpyCommandHost::getRequirement
const Requirement * getRequirement() const final
Definition: commands.hpp:604
sycl::_V1::detail::Command::emitEdgeEventForCommandDependence
void emitEdgeEventForCommandDependence(Command *Cmd, void *ObjAddr, bool IsCommand, std::optional< access::mode > AccMode=std::nullopt)
Creates an edge event when the dependency is a command.
Definition: commands.cpp:542
sycl::_V1::detail::EnqueueResultT
Result of command enqueueing.
Definition: commands.hpp:57
sycl::_V1::detail::DispatchHostTask
Definition: commands.cpp:310
sycl::_V1::detail::Command::supportsPostEnqueueCleanup
virtual bool supportsPostEnqueueCleanup() const
Returns true iff this command can be freed by post enqueue cleanup.
Definition: commands.cpp:742
sycl::_V1::detail::EmptyCommand::printDot
void printDot(std::ostream &Stream) const final
Definition: commands.cpp:1761
sycl::_V1::detail::Command::ALLOCA
@ ALLOCA
Definition: commands.hpp:107
sycl::_V1::detail::Command::HOST_TASK
@ HOST_TASK
Definition: commands.hpp:114
sycl::_V1::detail::MapMemObject
The map command enqueues mapping of device memory onto host memory.
Definition: commands.hpp:534
sycl::_V1::detail::tie
auto tie(Ts &...Args)
Definition: tuple.hpp:39
sycl::_V1::detail::Command::getQueue
const QueueImplPtr & getQueue() const
Definition: commands.hpp:172
sycl::_V1::detail::Command::emitInstrumentation
void emitInstrumentation(uint16_t Type, const char *Txt=nullptr)
Emits an event of Type.
Definition: commands.cpp:803
sycl::_V1::detail::kernel_impl
Definition: kernel_impl.hpp:34
sycl::_V1::detail::Command::EMPTY_TASK
@ EMPTY_TASK
Definition: commands.hpp:113
sycl::_V1::detail::Command::makeTraceEventEpilog
void makeTraceEventEpilog()
If prolog has been run, run epilog; this must be guarded by a check for xptiTraceEnabled().
Definition: commands.cpp:683
sycl::_V1::detail::Command::MIsBlockable
bool MIsBlockable
Indicates whether the command can be blocked from enqueueing.
Definition: commands.hpp:316
sycl::_V1::detail::Command::processDepEvent
Command * processDepEvent(EventImplPtr DepEvent, const DepDesc &Dep, std::vector< Command * > &ToCleanUp)
Perform glueing of events from different contexts.
Definition: commands.cpp:696
sycl::_V1::detail::EmptyCommand::addRequirement
void addRequirement(Command *DepCmd, AllocaCommandBase *AllocaCmd, const Requirement *Req)
Definition: commands.cpp:1714
sycl
Definition: access.hpp:18
sycl::_V1::detail::EmptyCommand
The empty command does nothing during enqueue.
Definition: commands.hpp:408
sycl::_V1::detail::Command::Marks::MToBeDeleted
bool MToBeDeleted
Used for marking the node for deletion during cleanup.
Definition: commands.hpp:324
sycl::_V1::detail::EnqueueResultT::SyclEnqueueBlocked
@ SyclEnqueueBlocked
Definition: commands.hpp:61
sycl::_V1::detail::Command::printDot
virtual void printDot(std::ostream &Stream) const =0
sycl::_V1::detail::KernelBundleImplPtr
std::shared_ptr< detail::kernel_bundle_impl > KernelBundleImplPtr
Definition: kernel_bundle.hpp:150
access.hpp
sycl::_V1::detail::KernelFusionCommand
The KernelFusionCommand is placed in the execution graph together with the individual kernels of the ...
Definition: commands.hpp:714
sycl::_V1::detail::Command::getPiEvents
std::vector< sycl::detail::pi::PiEvent > getPiEvents(const std::vector< EventImplPtr > &EventImpls) const
Collect PI events from EventImpls and filter out some of them in case of in order queue.
Definition: commands.cpp:233
sycl::_V1::detail::Command::addUser
void addUser(Command *NewUser)
Definition: commands.hpp:135
sycl::_V1::detail::Command::MSyncPointDeps
std::vector< sycl::detail::pi::PiExtSyncPoint > MSyncPointDeps
List of sync points for submissions to a command buffer.
Definition: commands.hpp:403
sycl::_V1::detail::ExecCGCommand::getCG
detail::CG & getCG() const
Definition: commands.hpp:652
sycl::_V1::detail::Command::MLeafCounter
unsigned MLeafCounter
Counts the number of memory objects this command is a leaf for.
Definition: commands.hpp:318
sycl::_V1::detail::Command::UPDATE_REQUIREMENT
@ UPDATE_REQUIREMENT
Definition: commands.hpp:112
sycl::_V1::detail::Command::getBlockReason
const char * getBlockReason() const
Definition: commands.cpp:946
sycl::_V1::detail::Command::FUSION
@ FUSION
Definition: commands.hpp:115
sycl::_V1::detail::EmptyCommand::producesPiEvent
bool producesPiEvent() const final
Returns true iff the command produces a PI event on non-host devices.
Definition: commands.cpp:1779
sycl::_V1::detail::AllocaSubBufCommand
The AllocaSubBuf command enqueues creation of sub-buffer of memory object.
Definition: commands.hpp:515
_pi_ext_command_buffer
Definition: pi_cuda.hpp:80
sycl::_V1::detail::Command::emitInstrumentationDataProxy
void emitInstrumentationDataProxy()
Proxy method which calls emitInstrumentationData.
Definition: commands.cpp:526
sycl::_V1::detail::EnqueueResultT::SyclEnqueueReady
@ SyclEnqueueReady
Definition: commands.hpp:59
sycl::_V1::detail::device_image_impl
Definition: device_image_impl.hpp:44
sycl::_V1::detail::Command::MDeps
std::vector< DepDesc > MDeps
Contains list of dependencies(edges)
Definition: commands.hpp:312
sycl::_V1::detail::DepDesc::MAllocaCmd
AllocaCommandBase * MAllocaCmd
Allocation command for the memory object we have requirement for.
Definition: commands.hpp:92
sycl::_V1::detail::Command::MFirstInstance
bool MFirstInstance
Flag to indicate if this is the first time we are seeing this payload.
Definition: commands.hpp:360
sycl::_V1::detail::NON_BLOCKING
@ NON_BLOCKING
Definition: commands.hpp:54
sycl::_V1::detail::UpdateHostRequirementCommand::getRequirement
const Requirement * getRequirement() const final
Definition: commands.hpp:701
sycl::_V1::detail::AllocaCommandBase::getRequirement
const Requirement * getRequirement() const final
Definition: commands.hpp:461
sycl::_V1::detail::ReleaseCommand
The release command enqueues release of a memory object instance allocated on Host or underlying fram...
Definition: commands.hpp:432
sycl::_V1::detail::BlockingT
BlockingT
Definition: commands.hpp:54
sycl::_V1::detail::DepDesc::DepDesc
DepDesc(Command *DepCommand, const Requirement *Req, AllocaCommandBase *AllocaCmd)
Definition: commands.hpp:77
sycl::_V1::detail::plugin
The plugin class provides a unified interface to the underlying low-level runtimes for the device-agn...
Definition: plugin.hpp:92
sycl::_V1::detail::Command::emitEdgeEventForEventDependence
void emitEdgeEventForEventDependence(Command *Cmd, sycl::detail::pi::PiEvent &EventAddr)
Creates an edge event when the dependency is an event.
Definition: commands.cpp:593
sycl::_V1::detail::Command::BlockReason
BlockReason
Definition: commands.hpp:329
sycl::_V1::detail::DepDesc::MDepRequirement
const Requirement * MDepRequirement
Requirement for the dependency.
Definition: commands.hpp:89
sycl::_V1::detail::Command::MAP_MEM_OBJ
@ MAP_MEM_OBJ
Definition: commands.hpp:110
sycl::_V1::detail::DepDesc::MDepCommand
Command * MDepCommand
The actual dependency command.
Definition: commands.hpp:87
sycl::_V1::detail::Command::MBlockedUsersMutex
std::mutex MBlockedUsersMutex
Definition: commands.hpp:391
sycl::_V1::detail::EnqueueResultT::MCmd
Command * MCmd
Pointer to the command which failed to enqueue.
Definition: commands.hpp:70
sycl::_V1::detail::Command::isBlocking
bool isBlocking() const
Definition: commands.hpp:163
sycl::_V1::detail::AllocaCommand
The alloca command enqueues allocation of instance of memory object on Host or underlying framework.
Definition: commands.hpp:495
sycl::_V1::detail::Command::getType
CommandType getType() const
Definition: commands.hpp:138
sycl::_V1::detail::Command::isFinished
bool isFinished()
sycl::_V1::detail::Command::addBlockedUserUnique
void addBlockedUserUnique(const EventImplPtr &NewUser)
Definition: commands.hpp:165
sycl::_V1::detail::Command::UNMAP_MEM_OBJ
@ UNMAP_MEM_OBJ
Definition: commands.hpp:111
sycl::_V1::detail::Command::waitForEvents
void waitForEvents(QueueImplPtr Queue, std::vector< EventImplPtr > &RawEvents, sycl::detail::pi::PiEvent &Event)
Definition: commands.cpp:444
sycl::_V1::detail::Command::MSubmissionCodeLocation
code_location MSubmissionCodeLocation
Represents code location of command submission to SYCL API, assigned with the valid value only if com...
Definition: commands.hpp:366
sycl::_V1::detail::Command::MBlockReason
BlockReason MBlockReason
Definition: commands.hpp:332
sycl::_V1::ext::oneapi::experimental::assert
assert(false)
sycl::_V1::detail::KernelArgMask
std::vector< bool > KernelArgMask
Definition: kernel_arg_mask.hpp:16
sycl::_V1::detail::Command::MCommandNodeType
std::string MCommandNodeType
Buffer to build the command node type.
Definition: commands.hpp:354
sycl::_V1::detail::DepDesc
Dependency between two commands.
Definition: commands.hpp:76
sycl::_V1::detail::Command::MEnqueueMtx
std::mutex MEnqueueMtx
Mutex used to protect enqueueing from race conditions.
Definition: commands.hpp:283
sycl::_V1::detail::Command::getEvent
const EventImplPtr & getEvent() const
Definition: commands.hpp:174
sycl::_V1::detail::HostTask
Definition: cg_types.hpp:232
sycl::_V1::detail::Command::MSubmissionFileName
std::string MSubmissionFileName
Introduces string to handle memory management since code_location struct works with raw char arrays.
Definition: commands.hpp:369
sycl::_V1::detail::pi::PiExtSyncPoint
::pi_ext_sync_point PiExtSyncPoint
Definition: pi.hpp:156
sycl::_V1::detail::MemCpyCommand
The mem copy command enqueues memory copy between two instances of memory object.
Definition: commands.hpp:573
sycl::_V1::detail::ReverseRangeDimensionsForKernel
void ReverseRangeDimensionsForKernel(NDRDescT &NDR)
Definition: commands.cpp:2211
sycl::_V1::detail::EnqueueResultT::ResultT
ResultT
Definition: commands.hpp:58
sycl::_V1::detail::Command::Marks
Definition: commands.hpp:320
sycl::_V1::detail::EventImplPtr
std::shared_ptr< event_impl > EventImplPtr
Definition: cg.hpp:39
program_manager.hpp
sycl::_V1::detail::Command::clearAllDependencies
void clearAllDependencies()
Clear all dependency events This should only be used if a command is about to be deleted without bein...
Definition: commands.hpp:305
sycl::_V1::detail::pi::PiKernel
::pi_kernel PiKernel
Definition: pi.hpp:138
sycl::_V1::detail::CGExecKernel
"Execute kernel" command group class.
Definition: cg.hpp:163
sycl::_V1::detail::Command::getPreparedDepsEvents
const std::vector< EventImplPtr > & getPreparedDepsEvents() const
Definition: commands.hpp:292
sycl::_V1::detail::EnqueueResultT::SyclEnqueueSuccess
@ SyclEnqueueSuccess
Definition: commands.hpp:60
sycl::_V1::detail::Command::MUsers
std::unordered_set< Command * > MUsers
Contains list of commands that depend on the command.
Definition: commands.hpp:314
sycl::_V1::detail::Command::waitForPreparedHostEvents
void waitForPreparedHostEvents() const
Definition: commands.cpp:439
sycl::_V1::detail::Command::RELEASE
@ RELEASE
Definition: commands.hpp:109
accessor_impl.hpp
sycl::_V1::detail::ExecCGCommand
The exec CG command enqueues execution of kernel or explicit memory operation.
Definition: commands.hpp:638
sycl::_V1::detail::NDRDescT
Definition: cg_types.hpp:53
sycl::_V1::detail::StreamImplPtr
std::shared_ptr< detail::stream_impl > StreamImplPtr
Definition: commands.hpp:45
sycl::_V1::detail::Command::CommandType
CommandType
Definition: commands.hpp:104
sycl::_V1::detail::EnqueueResultT::SyclEnqueueFailed
@ SyclEnqueueFailed
Definition: commands.hpp:62
sycl::_V1::detail::Command::Marks::MVisited
bool MVisited
Used for marking the node as visited during graph traversal.
Definition: commands.hpp:322
sycl::_V1::detail::Command::BlockReason::HostAccessor
@ HostAccessor
sycl::_V1::detail::MemCpyCommand::getRequirement
const Requirement * getRequirement() const final
Definition: commands.hpp:580
sycl::_V1::detail::MapMemObject::getRequirement
const Requirement * getRequirement() const final
Definition: commands.hpp:540
sycl::_V1::detail::Command::MAddress
void * MAddress
Reserved for storing the object address such as SPIR-V or memory object address.
Definition: commands.hpp:350
sycl::_V1::detail::AllocaSubBufCommand::getParentAlloca
AllocaCommandBase * getParentAlloca()
Definition: commands.hpp:524
sycl::_V1::detail::EnqueueResultT::MErrCode
pi_int32 MErrCode
Error code which is set when enqueueing fails.
Definition: commands.hpp:72
sycl::_V1::detail::code_location
Definition: common.hpp:66
sycl::_V1::detail::Command::MTraceEvent
void * MTraceEvent
The event for node_create and task_begin.
Definition: commands.hpp:343
sycl::_V1::detail::Command::MCommandName
std::string MCommandName
Buffer to build the command end-user understandable name.
Definition: commands.hpp:356
sycl::_V1::detail::enqueueImpCommandBufferKernel
pi_int32 enqueueImpCommandBufferKernel(context Ctx, DeviceImplPtr DeviceImpl, sycl::detail::pi::PiExtCommandBuffer CommandBuffer, const CGExecKernel &CommandGroup, std::vector< sycl::detail::pi::PiExtSyncPoint > &SyncPoints, sycl::detail::pi::PiExtSyncPoint *OutSyncPoint, const std::function< void *(Requirement *Req)> &getMemAllocationFunc)
Definition: commands.cpp:2396
sycl::_V1::detail::AllocaCommand::getMemAllocation
void * getMemAllocation() const final
Definition: commands.hpp:502
std
Definition: accessor.hpp:4171
sycl::_V1::detail::BLOCKING
@ BLOCKING
Definition: commands.hpp:54
_pi_event
Definition: pi_cuda.hpp:64
sycl::_V1::detail::Command::MWorkerQueue
QueueImplPtr MWorkerQueue
Definition: commands.hpp:250
sycl::_V1::detail::Command::MMarkedForCleanup
bool MMarkedForCleanup
Indicates that the node will be freed by graph cleanup.
Definition: commands.hpp:383
sycl::_V1::detail::Command::COPY_MEMORY
@ COPY_MEMORY
Definition: commands.hpp:106
sycl::_V1::detail::Command::makeTraceEventProlog
uint64_t makeTraceEventProlog(void *MAddress)
Create a trace event of node_create type; this must be guarded by a check for xptiTraceEnabled().
Definition: commands.cpp:651
sycl::_V1::detail::Command::getPreparedHostDepsEvents
const std::vector< EventImplPtr > & getPreparedHostDepsEvents() const
Definition: commands.hpp:288
sycl::_V1::detail::ArgDesc
Definition: cg_types.hpp:39
sycl::_V1::detail::QueueImplPtr
std::shared_ptr< sycl::detail::queue_impl > QueueImplPtr
Definition: event_impl.hpp:35
sycl::_V1::detail::EmptyCommand::EmptyCommand
EmptyCommand(QueueImplPtr Queue)
Definition: commands.cpp:1702
sycl::_V1::detail::DepDesc::operator<
friend bool operator<(const DepDesc &Lhs, const DepDesc &Rhs)
Definition: commands.hpp:81
sycl::_V1::detail::pi::PiExtCommandBuffer
::pi_ext_command_buffer PiExtCommandBuffer
Definition: pi.hpp:157
sycl::_V1::detail::Command::addDep
Command * addDep(DepDesc NewDep, std::vector< Command * > &ToCleanUp)
Definition: commands.cpp:749
sycl::_V1::detail::Command::getCommandBuffer
sycl::detail::pi::PiExtCommandBuffer getCommandBuffer() const
Gets the command buffer (if any) associated with this command.
Definition: commands.hpp:395
sycl::_V1::detail::SYCLMemObjI
Definition: sycl_mem_obj_i.hpp:28
sycl::_V1::detail::Command::MAddressString
std::string MAddressString
Buffer to build the address string.
Definition: commands.hpp:352
sycl::_V1::detail::Command::~Command
virtual ~Command()
Definition: commands.hpp:214
sycl::_V1::detail::kernel_bundle_impl
The class is an impl counterpart of the sycl::kernel_bundle.
Definition: kernel_bundle_impl.hpp:54
sycl::_V1::detail::AllocaCommandBase::getSYCLMemObj
SYCLMemObjI * getSYCLMemObj() const
Definition: commands.hpp:457
sycl::_V1::detail::Command::MPreparedHostDepsEvents
std::vector< EventImplPtr > & MPreparedHostDepsEvents
Definition: commands.hpp:255
sycl::_V1::detail::Command::Command
Command(CommandType Type, QueueImplPtr Queue, sycl::detail::pi::PiExtCommandBuffer CommandBuffer=nullptr, const std::vector< sycl::detail::pi::PiExtSyncPoint > &SyncPoints={})
It is safe to bind MPreparedDepsEvents and MPreparedHostDepsEvents references to event_impl class mem...
Definition: commands.cpp:501
sycl::_V1::detail::Command::enqueue
virtual bool enqueue(EnqueueResultT &EnqueueResult, BlockingT Blocking, std::vector< Command * > &ToCleanUp)
Checks if the command is enqueued, and calls enqueueImp.
Definition: commands.cpp:813
sycl::_V1::detail::Command::MPreparedDepsEvents
std::vector< EventImplPtr > & MPreparedDepsEvents
Dependency events prepared for waiting by backend.
Definition: commands.hpp:254
sycl::_V1::detail::Command::MStreamID
int32_t MStreamID
The stream under which the traces are emitted.
Definition: commands.hpp:347
sycl::_V1::detail::CG
Base class for all types of command groups.
Definition: cg.hpp:49
sycl::_V1::detail::enqueueReadWriteHostPipe
pi_int32 enqueueReadWriteHostPipe(const QueueImplPtr &Queue, const std::string &PipeName, bool blocking, void *ptr, size_t size, std::vector< sycl::detail::pi::PiEvent > &RawEvents, const detail::EventImplPtr &OutEventImpl, bool read)
Definition: commands.cpp:2617
sycl::_V1::detail::UpdateHostRequirementCommand
Definition: commands.hpp:695
sycl::_V1::detail::KernelFusionCommand::readyForDeletion
bool readyForDeletion() const
Definition: commands.hpp:742
sycl::_V1::detail::AllocaCommandBase
Base class for memory allocation commands.
Definition: commands.hpp:450
sycl::_V1::detail::Command::getWorkerQueue
const QueueImplPtr & getWorkerQueue() const
Get the queue this command will be submitted to.
Definition: commands.cpp:735
sycl::_V1::detail::Command::RUN_CG
@ RUN_CG
Definition: commands.hpp:105
sycl::_V1::detail::UnMapMemObject
The unmap command removes mapping of host memory onto device memory.
Definition: commands.hpp:553
sycl::_V1::detail::Command::MBlockedUsers
std::vector< EventImplPtr > MBlockedUsers
Contains list of commands that depends on the host command explicitly (by depends_on).
Definition: commands.hpp:390
sycl::_V1::detail::AllocaCommandBase::getReleaseCmd
ReleaseCommand * getReleaseCmd()
Definition: commands.hpp:455
sycl::_V1::detail::KernelFusionCommand::FusionStatus
FusionStatus
Definition: commands.hpp:716
sycl::_V1::detail::Command::MType
CommandType MType
The type of the command.
Definition: commands.hpp:281
sycl::_V1::detail::MemCpyCommandHost
The mem copy host command enqueues memory copy between two instances of memory object.
Definition: commands.hpp:597
sycl::_V1::detail::Command::MCommandBuffer
sycl::detail::pi::PiExtCommandBuffer MCommandBuffer
CommandBuffer which will be used to submit to instead of the queue, if set.
Definition: commands.hpp:401
sycl::_V1::detail::SetArgBasedOnType
void SetArgBasedOnType(const PluginPtr &Plugin, sycl::detail::pi::PiKernel Kernel, const std::shared_ptr< device_image_impl > &DeviceImageImpl, const std::function< void *(Requirement *Req)> &getMemAllocationFunc, const sycl::context &Context, bool IsHost, detail::ArgDesc &Arg, size_t NextTrueIndex)
Definition: commands.cpp:2231
sycl::_V1::detail::pi::PiEvent
::pi_event PiEvent
Definition: pi.hpp:143
sycl::_V1::detail::Command::producesPiEvent
virtual bool producesPiEvent() const
Returns true iff the command produces a PI event on non-host devices.
Definition: commands.cpp:740
sycl::_V1::detail::EnqueueResultT::EnqueueResultT
EnqueueResultT(ResultT Result=SyclEnqueueSuccess, Command *Cmd=nullptr, pi_int32 ErrCode=PI_SUCCESS)
Definition: commands.hpp:64
sycl::_V1::detail::Command::EXEC_CMD_BUFFER
@ EXEC_CMD_BUFFER
Definition: commands.hpp:116
sycl::_V1::detail::Command::isEnqueueBlocked
bool isEnqueueBlocked() const
Definition: commands.hpp:158
sycl::_V1::detail::Command::MEnqueueStatus
std::atomic< EnqueueResultT::ResultT > MEnqueueStatus
Describes the status of the command.
Definition: commands.hpp:335
pi_int32
int32_t pi_int32
Definition: pi.h:193
sycl::_V1::detail::enqueueImpKernel
pi_int32 enqueueImpKernel(const QueueImplPtr &Queue, NDRDescT &NDRDesc, std::vector< ArgDesc > &Args, const std::shared_ptr< detail::kernel_bundle_impl > &KernelBundleImplPtr, const std::shared_ptr< detail::kernel_impl > &MSyclKernel, const std::string &KernelName, std::vector< sycl::detail::pi::PiEvent > &RawEvents, const detail::EventImplPtr &OutEventImpl, const std::function< void *(Requirement *Req)> &getMemAllocationFunc, sycl::detail::pi::PiKernelCacheConfig KernelCacheConfig)
Definition: commands.cpp:2498
sycl::_V1::detail::applyFuncOnFilteredArgs
void applyFuncOnFilteredArgs(const KernelArgMask *EliminatedArgMask, std::vector< ArgDesc > &Args, std::function< void(detail::ArgDesc &Arg, int NextTrueIndex)> Func)
Definition: commands.cpp:111
sycl::_V1::detail::Command::ALLOCA_SUB_BUF
@ ALLOCA_SUB_BUF
Definition: commands.hpp:108
sycl::_V1::detail::Command::getWorkerContext
virtual const ContextImplPtr & getWorkerContext() const
Get the context of the queue this command will be submitted to.
Definition: commands.cpp:731
sycl::_V1::context
The context class represents a SYCL context on which kernel functions may be executed.
Definition: context.hpp:51
sycl::_V1::detail::Command::enqueueImp
virtual pi_int32 enqueueImp()=0
Private interface. Derived classes should implement this method.