AGX Dynamics 2.41.3.2
Loading...
Searching...
No Matches
Job.h
Go to the documentation of this file.
1/*
2Copyright 2007-2025. Algoryx Simulation AB.
3
4All AGX source code, intellectual property, documentation, sample code,
5tutorials, scene files and technical white papers, are copyrighted, proprietary
6and confidential material of Algoryx Simulation AB. You may not download, read,
7store, distribute, publish, copy or otherwise disseminate, use or expose this
8material unless having a written signed agreement with Algoryx Simulation AB, or having been
9advised so by Algoryx Simulation AB for a time limited evaluation, or having purchased a
10valid commercial license from Algoryx Simulation AB.
11
12Algoryx Simulation AB disclaims all responsibilities for loss or damage caused
13from using this software, unless otherwise stated in written agreements with
14Algoryx Simulation AB.
15*/
16
17#ifndef AGX_JOB_H
18#define AGX_JOB_H
19
20#ifdef _MSC_VER
21# pragma warning(push)
22# pragma warning(disable:4355) // Disable warnings about passing the 'this' pointer to base class constructors.
23# pragma warning(disable: 6011) // Disable warningC6011: dereferencing nullptr pointer
24#endif
25
26#include <agx/agxCore_export.h>
27#include <agx/IndexRange.h>
28#include <agx/Callback.h>
29
30#include <agx/Name.h>
31#include <agxData/Type.h>
32#include <agx/Event.h>
33#include <agx/Vector.h>
34#include <agx/Timer.h>
36#include <agx/SyncTag.h>
37#include <deque>
38
39
40
41
42namespace agx
43{
44 class Device;
45 class Task;
46 class Thread;
47
48 typedef class Job* JobPtr;
49
50
52 typedef std::deque<class Job *> JobPtrQueue;
53
54 class RangeJob;
56
63 {
64 public:
65 Job();
66 Job(const Job& other);
67 Job(const Callback& callback, agx::UInt32 costEstimate = 100);
68 virtual ~Job();
69
70 Job& operator=(const Job& other);
71
73 void init(const Callback& callback = Callback(), agx::UInt32 costEstimate = 100);
74
79 void addDependency(Job *parent);
80
85 void removeDependency(Job *parent);
86
91 bool hasDependency(Job *parent);
92
97 void removeAllDependencies();
98
103 void clearChildDependencies();
104
109 void setNumDependencies(agx::UInt32 numDependencies);
110
114 agx::UInt32 getNumDependencies() const;
115
119 void incrementNumDependencies(agx::UInt32 size = 1);
120
124 void decrementNumDependencies(agx::UInt32 size = 1);
125
129 const JobPtrVector& getChildDependencies() const;
130
134 const JobPtrVector& getParentDependencies() const;
135
139 void setCallback(const Callback& callback);
140
144 const Callback& getCallback() const;
145
151 bool resolve();
152
156 void spawn();
157
161 Thread *getTargetThread();
162
166 void setTargetThread(Thread *thread);
167
171 Task *getTask();
172
176 void setTask(Task *task);
177
181 SyncTag *getSyncTag();
182
186 void setSyncTag(SyncTag *tag);
187
191 Real getExecutionTime() const;
192
196 const Timer& getTimer() const;
197
201 void setCostEstimate(agx::UInt32 cost);
202
206 agx::UInt32 getCostEstimate() const;
207
211 Thread *getAssignedThread();
212
213
217 agx::UInt32 getTag() const;
218
222 void setTag(agx::UInt32 tag);
223
227 void setName(const char *name);
228
232 const char *getName() const;
233
234
238 agx::Index& index();
239 const agx::Index& index() const;
240
241 public:
242
246 virtual void implementation();
247
248 private:
253 void execute(JobPtrVector& resolvedChildren, Thread* thread);
254
255 protected:
256 friend class Thread;
257 friend class JobGroup;
258
259 const char *m_name;
265 std::atomic<Int32> m_dependencyCounter;
269 SyncTagRef m_syncTag;
273 };
274
276
277 //---------------------------------------------------------------
278
284 {
285 public:
287
288 public:
289 RangeJob();
290 RangeJob(const RangeCallback& callback, const IndexRange& range, agx::UInt32 costPerElement = 1);
291 RangeJob(const RangeJob& other);
292 virtual ~RangeJob();
293
294 void init(const RangeCallback& callback, const IndexRange& range, agx::UInt32 costPerElement = 1);
295 void init(const IndexRange& range, agx::UInt32 costPerElement = 1);
296
297 RangeJob& operator= (const RangeJob& other);
298
302 IndexRange& range();
303 const IndexRange& range() const;
304
305 protected:
306 virtual void implementation() override;
307
308 private:
309 // void dispatch();
310
311 protected:
314 };
315
317
318 //---------------------------------------------------------------
319
320 template <class T>
321 class RangeJobT : public RangeJob
322 {
323 public:
324 RangeJobT();
325 RangeJobT(const RangeCallback& callback, const IndexRange& range, agx::UInt32 costPerElement = 1);
326 RangeJobT(const RangeJobT<T>& other);
327
328 virtual ~RangeJobT();
329
330 protected:
331 virtual void implementation() override;
332 };
333
334 //---------------------------------------------------------------
335
341 {
342 public:
343 JobGroup();
344 virtual ~JobGroup();
345
346 void init();
347
348 void addJob(Job *job);
349 const JobPtrVector& getSubJobs() const;
350
351 // void execute();
352
353 protected:
354 virtual void implementation() override;
355
356 private:
357 JobPtrVector m_jobs;
358 };
359
360 //---------------------------------------------------------------
361
366 {
367 public:
369 virtual ~WaitJob();
370
374 void wait();
375
379 void release();
380
384 Job *getTarget();
385 const Job *getTarget() const;
386
387 private:
388 Job *m_target;
389 Block m_block;
390 };
391
392 //---------------------------------------------------------------
393
398 {
399 public:
400 TaskJob();
401 TaskJob(Task *task);
402 virtual ~TaskJob();
403
404 void init(Task *task);
405 void init();
406
407 void execute();
408
409 private:
410 Task *m_target;
411 };
412
413
414
415
416
417 /* Implementation */
418
421 Callback(&Job::spawn, this),
422 m_name(""),
423 m_numDependencies(0),
424 m_dependencyCounter(0),
425 m_task(nullptr),
426 m_targetThread(nullptr),
427 m_assignedThread(nullptr),
428 m_cost(0),
429 m_tag(0),
430 m_index(InvalidIndex)
431 {
432 }
433
435 Callback(&Job::spawn, this),
436 m_name(other.m_name),
437 m_children(other.m_children),
438 m_parents(other.m_parents),
439 m_callback(other.m_callback),
440 m_timer(other.m_timer),
441 m_numDependencies(other.m_numDependencies),
442 m_dependencyCounter(other.m_dependencyCounter.load()),
443 m_task(other.m_task),
444 m_targetThread(other.m_targetThread),
445 m_assignedThread(other.m_assignedThread),
446 m_syncTag(other.m_syncTag),
447 m_cost(other.m_cost),
448 m_tag(other.m_tag),
449 m_index(other.m_index)
450 {
451 }
452
453
454
455 AGX_FORCE_INLINE Job::Job(const Callback& callback, agx::UInt32 costEstimate) :
456 Callback(&Job::spawn, this),
457 m_name(""),
458 m_callback(callback),
459 m_numDependencies(0),
460 m_dependencyCounter(0),
461 m_task(nullptr),
462 m_targetThread(nullptr),
463 m_assignedThread(nullptr),
464 m_cost(costEstimate),
465 m_tag(0),
466 m_index(InvalidIndex)
467 {
468 }
469
471 {
472 m_name = other.m_name;
473 m_children = other.m_children;
474 m_parents = other.m_parents;
475 m_callback = other.m_callback;
476 m_timer = other.m_timer;
479 m_task = other.m_task;
482 m_syncTag = other.m_syncTag;
483 m_cost = other.m_cost;
484 m_tag = other.m_tag;
485 m_index = other.m_index;
486
487 return *this;
488 }
489
490 AGX_FORCE_INLINE const char *Job::getName() const { return m_name; }
491 AGX_FORCE_INLINE void Job::setName(const char *name) { m_name = name; }
492
496 AGX_FORCE_INLINE void Job::setTask(Task *task) { m_task = task; }
498 AGX_FORCE_INLINE void Job::setSyncTag(SyncTag *tag) { m_syncTag = tag; }
500
503
504
506 {
507 agxAssert(parent);
508 // agxAssert(!parent->m_children.contains(this));
509 parent->m_children.push_back(this);
511 #ifdef AGX_DEBUG
512 m_parents.push_back(parent);
513 #endif
514 }
515
516
518 {
519 agxAssert(parent);
520 // agxAssert(parent->m_children.contains(this));
521 if (parent->m_children.findAndErase(this)) {
523 #ifdef AGX_DEBUG
525 #endif
526 }
527 }
528
529
531 {
532 agxAssert(parent);
533 return parent->m_children.contains(this);
534 }
535
537
539 AGX_FORCE_INLINE void Job::setNumDependencies(agx::UInt32 numDependencies) { m_numDependencies = numDependencies; }
541 {
543 #ifdef AGX_DEBUG
545 #endif
546 }
547
551
553
554 AGX_FORCE_INLINE void Job::setCallback(const Callback& callback) { m_callback = callback; }
556
557
558 AGX_FORCE_INLINE void Job::init(const Callback& callback, agx::UInt32 costEstimate)
559 {
560 this->setNumDependencies(0);
562
563 #ifdef AGX_DEBUG
565 #endif
566
567 m_callback = callback;
568 m_cost = costEstimate;
569 m_targetThread = nullptr;
570 m_assignedThread = nullptr;
571 m_tag = 0;
572 m_index = 0;
573 }
574
576 AGX_FORCE_INLINE const Timer& Job::getTimer() const { return m_timer; }
579
582
583
585
586 AGX_FORCE_INLINE JobGroup::JobGroup() // : Job(Callback(&JobGroup::execute, this))
587 {
588 }
589
591 {
592 // Job::init(Callback(&JobGroup::execute, this));
594 m_jobs.clear();
595 m_cost = 0;
596 }
597
599 {
600 m_jobs.push_back(job);
601 m_cost += job->getCostEstimate();
602 }
603
605 {
606 return m_jobs;
607 }
608
609
610
612 AGX_FORCE_INLINE RangeJob::RangeJob() // : Job(Callback(&RangeJob::dispatch, this))
613 {}
614
615 AGX_FORCE_INLINE RangeJob::RangeJob(const RangeCallback& callback, const IndexRange& range, agx::UInt32 costPerElement) // : Job(Callback(&RangeJob::dispatch, this))
616 {
617 this->init(callback, range, costPerElement);
618 }
619
620 AGX_FORCE_INLINE RangeJob::RangeJob(const RangeJob& other) : Job(other) // : Job(Callback(&RangeJob::dispatch, this))
621 {
622 *this = other;
623 }
624
626 {
627 this->init(other.m_rangeCallback, other.m_range);
628 return *this;
629 }
630
633
634
635 AGX_FORCE_INLINE void RangeJob::init(const RangeCallback& callback, const IndexRange& range, agx::UInt32 costPerElement)
636 {
637 m_range = range;
638 m_rangeCallback = callback;
639
640 Job::init(Callback(), (agx::UInt32)m_range.size() * costPerElement);
641 }
642
643 AGX_FORCE_INLINE void RangeJob::init(const IndexRange& range, agx::UInt32 costPerElement)
644 {
645 m_range = range;
646 Job::init(Callback(), (agx::UInt32)m_range.size() * costPerElement);
647 }
648
650
651 template <class T>
653 {}
654
655 template <class T>
656 AGX_FORCE_INLINE RangeJobT<T>::RangeJobT(const RangeCallback& callback, const IndexRange& range, agx::UInt32 costPerElement)
657 : RangeJob(callback, range, costPerElement)
658 {}
659
660 template <class T>
662 {}
663
664 template <class T>
666 {
667 }
668
669 template <class T>
671 {
672 agxAssert(dynamic_cast<T *>(m_task));
673 static_cast<T *>(m_task)->dispatch(*this);
674 }
675
677 AGX_FORCE_INLINE TaskJob::TaskJob() : Job(Callback(&TaskJob::execute, this)), m_target(nullptr)
678 {
679 }
680
681 AGX_FORCE_INLINE TaskJob::TaskJob(Task* task) : Job(Callback(&TaskJob::execute, this)), m_target(task)
682 {
683 }
684
686 {
688 m_target = task;
689 }
690
692 {
694 }
695
697
699 AGX_FORCE_INLINE const Job *WaitJob::getTarget() const { return m_target; }
700
701}
702
704AGX_TYPE_BINDING(agx::RangeJob, "RangeJob")
705AGX_TYPE_BINDING(agx::JobGroup, "JobGroup")
706AGX_TYPE_BINDING(agx::TaskJob, "TaskJob")
707
708
709#ifdef _MSC_VER
710# pragma warning(pop)
711#endif
712
713#endif /* _AGX_JOB_H_ */
#define AGX_TYPE_BINDING(_Type, _Name)
Definition: Type.h:179
#define AGXCORE_EXPORT
Block synchronization primitive.
Templated callback with one argument.
Definition: Callback.h:101
Generalized callback, using std::function.
Definition: Callback.h:54
T size() const
Definition: IndexRange.h:168
A group of jobs to be executed.
Definition: Job.h:341
JobGroup()
Definition: Job.h:586
void init()
Definition: Job.h:590
virtual ~JobGroup()
const JobPtrVector & getSubJobs() const
Definition: Job.h:604
virtual void implementation() override
Job implementation, override in subclass.
void addJob(Job *job)
Definition: Job.h:598
An abstract job/workblock representation, which allows work threads to execute arbitrary tasks.
Definition: Job.h:63
void setTask(Task *task)
Set the task which the job belongs to.
Definition: Job.h:496
void removeDependency(Job *parent)
Remove a dependency from a job.
Definition: Job.h:517
Job()
Definition: Job.h:420
agx::UInt32 getCostEstimate() const
Definition: Job.h:577
bool hasDependency(Job *parent)
Definition: Job.h:530
void setNumDependencies(agx::UInt32 numDependencies)
Explicitly set the number of parent dependencies.
Definition: Job.h:539
Real getExecutionTime() const
Definition: Job.h:575
void spawn()
Schedule job for execution in thread pool.
Task * m_task
Definition: Job.h:266
agx::UInt32 getNumDependencies() const
Definition: Job.h:548
agx::UInt32 m_tag
Definition: Job.h:271
Timer m_timer
Definition: Job.h:263
Thread * getTargetThread()
Definition: Job.h:493
Job & operator=(const Job &other)
Definition: Job.h:470
Task * getTask()
Definition: Job.h:495
const Timer & getTimer() const
Definition: Job.h:576
void addDependency(Job *parent)
Add a dependency to a job.
Definition: Job.h:505
Callback m_callback
Definition: Job.h:262
const char * m_name
Definition: Job.h:259
SyncTag * getSyncTag()
Definition: Job.h:497
JobPtrVector m_children
Definition: Job.h:260
void setTargetThread(Thread *thread)
Set the target thread which the job will be executed on.
Definition: Job.h:494
agx::UInt32 getTag() const
Definition: Job.h:501
agx::Index m_index
Definition: Job.h:272
Thread * m_targetThread
Definition: Job.h:267
JobPtrVector m_parents
Definition: Job.h:261
const JobPtrVector & getChildDependencies() const
Definition: Job.h:552
void setTag(agx::UInt32 tag)
Set the job tag, can be used to keep track of different job classes etc.
Definition: Job.h:502
SyncTagRef m_syncTag
Definition: Job.h:269
void setCostEstimate(agx::UInt32 cost)
Specify the cost estimate for this job.
Definition: Job.h:578
std::atomic< Int32 > m_dependencyCounter
Definition: Job.h:265
void decrementNumDependencies(agx::UInt32 size=1)
Explicitly decrement the number of parent dependencies.
Definition: Job.h:550
virtual void implementation()
Job implementation, override in subclass.
const char * getName() const
Definition: Job.h:490
const Callback & getCallback() const
Return the current callback.
Definition: Job.h:555
void init(const Callback &callback=Callback(), agx::UInt32 costEstimate=100)
Initialize the job.
Definition: Job.h:558
void incrementNumDependencies(agx::UInt32 size=1)
Explicitly increment the number of parent dependencies.
Definition: Job.h:549
void clearChildDependencies()
Remove all child dependencies.
Definition: Job.h:538
void removeAllDependencies()
Remove all parent dependencies.
Definition: Job.h:540
Thread * m_assignedThread
Definition: Job.h:268
void setName(const char *name)
Set the name of the job, for debugging.
Definition: Job.h:491
agx::UInt32 m_cost
Definition: Job.h:270
bool resolve()
Increase the dependency counter for the job, and queue job for execution if all dependencies are reso...
void setSyncTag(SyncTag *tag)
Set the synchronization tag which must enter completion status before the job is executed.
Definition: Job.h:498
const JobPtrVector & getParentDependencies() const
Definition: Job.h:536
virtual ~Job()
void setCallback(const Callback &callback)
Set the callback which is called when execute() runs.
Definition: Job.h:554
agx::Index & index()
Definition: Job.h:580
Thread * getAssignedThread()
Definition: Job.h:499
agx::UInt32 m_numDependencies
Definition: Job.h:264
virtual ~RangeJobT()
Definition: Job.h:665
RangeJobT()
Definition: Job.h:652
virtual void implementation() override
Job implementation, override in subclass.
Definition: Job.h:670
A range job executes a kernel implementation on a subset of the data.
Definition: Job.h:284
void init(const RangeCallback &callback, const IndexRange &range, agx::UInt32 costPerElement=1)
Definition: Job.h:635
virtual void implementation() override
Job implementation, override in subclass.
RangeCallback m_rangeCallback
Definition: Job.h:312
virtual ~RangeJob()
IndexRange m_range
Definition: Job.h:313
RangeJob()
Definition: Job.h:612
IndexRange & range()
Definition: Job.h:631
RangeJob & operator=(const RangeJob &other)
Definition: Job.h:625
A task job is a job which executes an agx::Task.
Definition: Job.h:398
TaskJob()
Definition: Job.h:677
void init()
Definition: Job.h:691
virtual ~TaskJob()
void execute()
A representation of a generic task.
Definition: Task.h:58
agx::Thread is a representation of an OS specific implementation of a computational thread.
Definition: Thread.h:200
The Timer class permits timing execution speed with the same refinement as the built in hardware cloc...
Definition: Timer.h:62
Real64 getTime() const
Report total elapsed time since start in milliseconds, excluding intervals when the timer was suspend...
Definition: Timer.h:191
Vector containing 'raw' data.
Definition: agx/Vector.h:246
void push_back(const T &value)
Definition: agx/Vector.h:1362
bool contains(const T2 &element) const
Test if the vector contains a certain element.
Definition: agx/Vector.h:1452
bool findAndErase(const T &element, bool searchMultiple=false)
Find and erase an element.
Definition: agx/Vector.h:1478
void clear(ClearPolicy policy=SHRINK_BUFFER_AVERAGED)
Remove all elements, optionally with maintained buffer allocation.
Definition: agx/Vector.h:1149
Templated vector class.
Definition: agx/Vector.h:53
A job used as a synchronization utility when waiting for another job to complete.
Definition: Job.h:366
virtual ~WaitJob()
void release()
Release the waiting thread.
Job * getTarget()
Definition: Job.h:698
void wait()
Blocks until the targeted job is completed.
WaitJob(Job *job)
#define agxVerify(expr)
Definition: debug.h:131
#define agxAssert(expr)
Definition: debug.h:143
#define AGX_FORCE_INLINE
Definition: macros.h:58
The agx namespace contains the dynamics/math part of the AGX Dynamics API.
uint32_t UInt32
Definition: Integer.h:32
Vector< RangeJob > RangeJobVector
Definition: Job.h:316
Vector< Job > JobVector
Definition: Job.h:275
double Real
Definition: Real.h:42
VectorPOD< class Job * > JobPtrVector
Definition: Job.h:51
std::deque< class Job * > JobPtrQueue
Definition: Job.h:52
AGXCORE_EXPORT const InvalidIndexStruct InvalidIndex
agx::Callback1< const RangeJob & > RangeCallback
Definition: Job.h:55
void AGXPHYSICS_EXPORT init()
Initialize AGX Dynamics API including thread resources and must be executed before using the AGX API.
class Job * JobPtr
Definition: Job.h:48
UInt32 Index
Definition: Integer.h:44