This interface represents the base class for all fragmented jobs. More...
#include <dice.h>
Public Types | |
enum | Scheduling_mode { LOCAL = 0 , CLUSTER = 1 , ONCE_PER_HOST = 2 , USER_DEFINED = 3 , SCHEDULING_MODE_FORCE_32_BIT = 0xffffffffU } |
Constants for possible scheduling modes. More... | |
Public Types inherited from mi::base::Interface_declare< 0x037f3783, ... > | |
typedef Interface_declare< id1, ... > | Self |
Own type. More... | |
typedef Uuid_t< id1, ... > | IID |
Declares the interface ID (IID) of this interface. More... | |
Public Types inherited from mi::base::Interface_declare< 0x7a70f2fb, ... > | |
typedef Interface_declare< id1, ... > | Self |
Own type. More... | |
typedef Uuid_t< id1, ... > | IID |
Declares the interface ID (IID) of this interface. More... | |
Public Types inherited from mi::base::IInterface | |
typedef Uuid_t<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0> | IID |
Declares the interface ID (IID) of this interface. More... | |
Public Member Functions | |
virtual void | execute_fragment (IDice_transaction *transaction, Size index, Size count, const IJob_execution_context *context)=0 |
Executes one of many fragments of the fragmented job on the local host. More... | |
virtual void | execute_fragment_remote (ISerializer *serializer, IDice_transaction *transaction, Size index, Size count, const IJob_execution_context *context)=0 |
Executes one of many fragments of the fragmented job on a remote host. More... | |
virtual void | receive_remote_result (IDeserializer *deserializer, IDice_transaction *transaction, Size index, Size count)=0 |
Receives the result generated by the remote execution of a fragment. More... | |
virtual IRDMA_buffer * | get_rdma_result_buffer (IRDMA_context *rdma_context, Size index)=0 |
Returns an RDMA buffer to be used for the result of the fragment. More... | |
virtual IRDMA_buffer * | execute_fragment_remote_rdma (IDice_transaction *transaction, Size index, Size count, IRDMA_context *rdma_context, const IJob_execution_context *context)=0 |
Executes one of many fragments of the fragmented job on a remote host (RDMA variant). More... | |
virtual void | receive_remote_result_rdma (IRDMA_buffer *buffer, IDice_transaction *transaction, Size index, Size count)=0 |
Receives the result generated by the remote execution of a fragment (RDMA variant). More... | |
virtual void | serialize (ISerializer *serializer) const =0 |
Serializes the fragmented job to enable remote job execution of fragments. More... | |
virtual void | deserialize (IDeserializer *deserializer)=0 |
Deserializes the fragmented job to enable remote job execution of fragments. More... | |
virtual void | assign_fragments_to_hosts (Uint32 *slots, Size nr_slots)=0 |
Static assignment of fragments to hosts in the cluster. More... | |
virtual Scheduling_mode | get_scheduling_mode () const =0 |
Returns the scheduling mode. More... | |
virtual Float32 | get_cpu_load () const =0 |
Returns the CPU load per fragment of the fragmented job. More... | |
virtual Float32 | get_gpu_load () const =0 |
Returns the GPU load per fragment of the fragmented job. More... | |
virtual void | cancel ()=0 |
Cancels the execution of not yet completed jobs. More... | |
virtual Sint8 | get_priority () const =0 |
Returns the priority of the job. More... | |
virtual Size | get_thread_limit () const =0 |
Returns the maximum number of threads that should be used to execute the fragments of this job. More... | |
virtual bool | get_allow_non_sequential_chunks () const =0 |
Indicates whether chunks can be delivered out of order. More... | |
Public Member Functions inherited from mi::neuraylib::ISerializable | |
virtual base::Uuid | get_class_id () const =0 |
Returns the class ID of the object. More... | |
virtual void | serialize (ISerializer *serializer) const =0 |
Serializes the object to the given serializer . More... | |
virtual void | deserialize (IDeserializer *deserializer)=0 |
Deserializes the object from the given deserializer . More... | |
Public Member Functions inherited from mi::base::IInterface | |
virtual Uint32 | retain () const =0 |
Increments the reference count. More... | |
virtual Uint32 | release () const =0 |
Decrements the reference count. More... | |
virtual const IInterface * | get_interface (const Uuid &interface_id) const =0 |
Acquires a const interface from another. More... | |
template<class T> | |
const T * | get_interface () const |
Acquires a const interface from another. More... | |
virtual IInterface * | get_interface (const Uuid &interface_id)=0 |
Acquires a mutable interface from another. More... | |
template<class T> | |
T * | get_interface () |
Acquires a mutable interface from another. More... | |
virtual Uuid | get_iid () const =0 |
Returns the interface ID of the most derived interface. More... | |
Additional Inherited Members | |
Static Public Member Functions inherited from mi::base::Interface_declare< 0x037f3783, ... > | |
static bool | compare_iid (const Uuid &iid) |
Compares the interface ID iid against the interface ID of this interface and of its ancestors. More... | |
Static Public Member Functions inherited from mi::base::Interface_declare< 0x7a70f2fb, ... > | |
static bool | compare_iid (const Uuid &iid) |
Compares the interface ID iid against the interface ID of this interface and of its ancestors. More... | |
Static Public Member Functions inherited from mi::base::IInterface | |
static bool | compare_iid (const Uuid &iid) |
Compares the interface ID iid against the interface ID of this interface. More... | |
This interface represents the base class for all fragmented jobs.
Each fragmented job must be derived from the this interface.
Fragmented jobs enable distributing compute intensive work to the CPUs and/or GPUs available in a cluster environment.
Compared to a database jobs, fragmented jobs are lightweight means to achieve distributed, parallel computing in a cluster. Fragmented jobs differ from database jobs as follows:
In general, a fragmented job should be used if the result of the parallel algorithm is used only once by the host initiating the execution. For instance, a fragmented job for rendering may initiate the rendering of a single frame.
Constants for possible scheduling modes.
Enumerator | |
---|---|
LOCAL | All fragments will be done on the local host. In consequence, dummy implementations for serialize() and deserialize() as well as for execute_fragment_remote() and receive_remote_result() suffice. |
CLUSTER | The fragments will be spread across all hosts in the cluster. If a fragment fails to execute on a given host (for example, due to a host leaving the cluster), it is re-assinged to a different host such that fragments are guaranteed to be executed.
|
ONCE_PER_HOST | At most one fragment will be done per remote host. If the specified number of fragments is larger than zero and less than the number of remote hosts then only some hosts will get a fragment. To ensure that exactly one fragment will be done per remote host the number of fragments should be set to the special value 0. This mode is not possible for jobs which need a GPU.
|
USER_DEFINED | The job implements an explicit assignment of fragments to hosts and must implement the assign_fragments_to_hosts() function to fill out all slots. Fragments assigned to hosts which are unknown will be skipped. If a host fails during fragment execution, its workload will not be re-assinged to a different host |
|
pure virtual |
Static assignment of fragments to hosts in the cluster.
The static assignment of fragments to hosts in the cluster overrides the DiCE built-in scheduling of fragments to hosts by providing an array of host IDs that are mapped to the fragments' indices, i.e., by assigning fragments to hosts explicitly.
Example: The array 1, 2, 2, 2, 3 would map the first fragment with index 0 to host ID 1, the next three fragments to host ID 2, and the last fragment with index 4 to host ID 3.
A typical use case for static assignments represent sort-last algorithms. Sort-last algorithms subdivide the (huge) data to be processed into smaller portions and then delegate the smaller portions to hosts once. This avoids network transfers while the processing the data later. The static assignment then ensure that the fragment for processing a certain portion of the data are scheduled for the host in the cluster where the portion resides.
Care should be taken when implementing a static user-defined assignment. Usually, the DiCE built-in scheduler balances the workload of compute intensive tasks itself. The static user-defined assignment of jobs to hosts circumvents this feature which might results in an unbalanced non-scalable system when done improperly.
slots | Pointer to an array of host IDs. The i-th element is the host ID of the i-th fragment. |
nr_slots | The size of the array slots . |
|
pure virtual |
Cancels the execution of not yet completed jobs.
This method is called if the job has been submitted for execution, but not all its fragments have been completed when the transaction is closed or aborted. If the job result is no longer needed in such a case, this notification can be used to terminate currently running fragments and/or skip the execution of not yet started fragments.
|
pure virtual |
Deserializes the fragmented job to enable remote job execution of fragments.
The method creates a replica of the serialized original fragmented job instance on the remote host. The deserialized replica is used for all fragments of a fragmented job that are executed on that particular host, i.e., they all share the same data. In consequence, the class may additionally generate data required by all fragments, like caches, etc.
deserializer | The deserializer from which to read the job content. |
Implements mi::neuraylib::ISerializable.
|
pure virtual |
Executes one of many fragments of the fragmented job on the local host.
Executes one fragment of the many fragments spawned by the fragmented job. This method is used for fragments executed on the calling host only and, thus, operates on the original instance of the fragmented job class and not on a copy.
Note that other fragments operating on the same instance might be executed in parallel. Therefore all accesses to instance data need to be properly serialized.
transaction | The transaction in which the fragmented job is executed. The transaction can be used to access database elements and database jobs required for execution but should not be used to edit or create tags. Might be NULL if the fragmented job was started without transaction. |
index | The index of the fragment to be executed. The value is in the range from 0 to count-1 . |
count | The number of fragments into which the fragmented job is split. |
context | The context in which the fragmented job is executed. |
|
pure virtual |
Executes one of many fragments of the fragmented job on a remote host.
Executes one fragment of the many fragments spawned by the fragmented job on a remote host. The remote execution requires the remote host to generate a replica of the original fragmented job instance using serialize() on the local host and deserialize() on the remote host.
Note that all fragments of a fragmented job which are executed on the same host will use the same replica of the original fragmented job instance. That means the replica can contain data shared between different fragments, like caches, etc.
As in the case of local execution other fragments executed on that host might be executed in parallel. Therefore all accesses to instance data need to be properly synchronized.
Intermediate results can be returned by calling mi::neuraylib::ISerializer::flush() on serializer
. All data serialized until that point will be delivered in a single call to receive_remote_result(). When execute_fragment_remote() returns any data not yet flushed will be flushed and receive_remote_result() will be called one last time with that data.
serializer | The serializer used to send the result of that fragment back to the initiating host (see receive_remote_result()). |
transaction | The transaction in which the fragmented job is executed. The transaction can be used to access database elements and database jobs required for execution but should not be used to edit or create tags. |
index | The index of the fragment to be executed. The value is in the range from 0 to count-1 . |
count | The number of fragments into which the fragmented job is split. |
context | The context in which the fragmented job is executed. |
|
pure virtual |
Executes one of many fragments of the fragmented job on a remote host (RDMA variant).
Executes one fragment of the many fragments spawned by the fragmented job on a remote host. The remote execution requires the remote host to generate a replica of the original fragmented job instance using serialize() on the local host and deserialize() on the remote host.
Note that all fragments of a fragmented job which are executed on the same host will use the same replica of the the original fragmented job instance. That means the replica can contain data shared between different fragments, like caches, etc.
As in the case of local execution other fragments executed on that host might be executed in parallel. Therefore all accesses to instance data need to be properly synchronized.
transaction | The transaction in which the fragmented job is executed. The transaction can be used to access database elements and database jobs required for execution but should not be used to edit or create tags. |
index | The index of the fragment to be executed. The value is in the range from 0 to count-1 . |
count | The number of fragments into which the fragmented job is split. |
rdma_context | The RDMA context to acquire RDMA buffers from for this host. |
context | The context in which the fragmented job is executed. |
rdma_context
) or NULL
if no result is to be send back from this fragment. The same RDMA buffer can be returned from multiple fragments and from different jobs, in that case it will be sent back as the result of all the fragments using it. rdma_context
will fail if its size exceeds the size of the RDMA buffer allocated for this fragment on the receiver side.
|
pure virtual |
Indicates whether chunks can be delivered out of order.
|
pure virtual |
Returns the CPU load per fragment of the fragmented job.
Typically 1.0 for CPU jobs and 0.0 for GPU jobs. A value larger than 1.0 might be used for jobs that concurrently use multiple threads per fragment, e.g., if OpenMP or MPI is used. A value between 0.0 and 1.0 might be used for jobs that do not much work themselves, but are rather used as synchronization primitive.
|
pure virtual |
Returns the GPU load per fragment of the fragmented job.
Typically 0.0 for CPU jobs and 1.0 for GPU jobs. A value larger than 1.0 might be used for jobs that concurrently use multiple GPUs per fragment. A value between 0.0 and 1.0 might be used for jobs that do not much work themselves, but are rather used as synchronization primitive.
|
pure virtual |
Returns the priority of the job.
The smaller the value the higher the priority of the job to be executed.
|
pure virtual |
Returns an RDMA buffer to be used for the result of the fragment.
Used to allocate an RDMA buffer which will be used to store the result of a fragment execution on a remote host. This method is only called for fragments which are executed on remote hosts. The RDMA buffer must be obtained from the given RDMA context.
If the method returns a valid RDMA buffer, the methods execute_fragment_remote_rdma() and receive_remote_result_rdma() are used instead of execute_fragment_remote() and receive_remote_result() to execute a fragment and to receive its result.
The RDMA buffer must at least be able to store the maximum expected result of the fragment execution.
rdma_context | RDMA context to acquire buffers from for this host. |
index | The index of the fragment to be executed. |
NULL
if RDMA should not be used.
|
pure virtual |
Returns the scheduling mode.
|
pure virtual |
Returns the maximum number of threads that should be used to execute the fragments of this job.
With certain job patterns a large number of threads might be used to execute as many fragments as possible in parallel. This property can be used to limit the number of threads, potentially at the cost of performance. The special value 0 means no limit on the number of threads.
|
pure virtual |
Receives the result generated by the remote execution of a fragment.
This method is called by the host that initiated the fragmented job execution for each fragment that has been executed on a remote host. The method receives via deserializer
the data that has been written to the serializer on the remote host by execute_fragment_remote().
This method is called on the original instance of the fragmented job. Note that other fragments operating on the same instance might receive their result in parallel. Therefore all accesses to instance data need to be properly serialized.
Essentially, the remote execution of fragments of a fragmented job using execute_fragment_remote() on the remote host and receive_remote_result() on the local host should have the same effect as executing execute_fragment() on the local host.
The remote execution of a fragment might produce intermediate results by flushing the data serialized so far. Each call to mi::neuraylib::ISerializer::flush() on the remote host will result in a single call to receive_remote_result() on the local host, even if no data was flushed. When the execution on the remote host finishes this method will be called one last time with the remaining data.
deserializer | The deserializer used to receive the result of that fragment from the remote host. |
transaction | The transaction in which the fragmented job is executed. The transaction can be used to access database elements and database jobs required for execution but should not be used to edit or create tags. |
index | The index of the fragment to be executed. The value is in the range from 0 to count-1 . |
count | The number of fragments into which the fragmented job is split. |
|
pure virtual |
Receives the result generated by the remote execution of a fragment (RDMA variant).
This method is called by the host that initiated the fragmented job execution for each fragment that has been executed on a remote host. The method receives via buffer
the data that has been returned in the RDMA buffer on the remote host by execute_fragment_remote_rdma().
This method is called on the original instance of the fragmented job. Note that other fragments operating on the same instance might receive their result in parallel. Therefore all accesses to instance data need to be properly serialized.
Essentially, the remote execution of fragments of a fragmented job using execute_fragment_remote_rdma() on the remote host and receive_remote_result_rdma() on the local host should have the same effect as executing execute_fragment() on the local host.
buffer | The RDMA buffer obtained from get_rdma_result_buffer(). It contains the data returned by execute_fragment_remote_rdma() on the remote host. The data might be processed immediately, but it is also possible to retain the buffer and to process it later. |
transaction | The transaction in which the fragmented job is executed. The transaction can be used to access database elements and database jobs required for execution but should not be used to edit or create tags. |
index | The index of the fragment to be executed. The value is in the range from 0 to count-1 . |
count | The number of fragments into which the fragmented job is split. |
|
pure virtual |
Serializes the fragmented job to enable remote job execution of fragments.
The serialization shall include all members required for remote fragment execution. If the fragmented job references objects by means of tags it suffices to serializes the tags only. The remote execution can then access these tags and the distributed database ensures that the objects get transferred to the requesting remote host.
serializer | The serializer to which to write the job content to. |
Implements mi::neuraylib::ISerializable.