Commit 28ea6ab3 by Marcus Winter

mtapi_cpp: added functionality to start Function objects directly as a task

parent ea2bc757
...@@ -118,7 +118,7 @@ class ExecutionPolicy{ ...@@ -118,7 +118,7 @@ class ExecutionPolicy{
* *
* \return the affinity * \return the affinity
*/ */
const mtapi_affinity_t &GetAffinity() const; mtapi_affinity_t GetAffinity() const;
/** Returns the priority /** Returns the priority
* *
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
* \ingroup CPP * \ingroup CPP
*/ */
#include <embb/mtapi/execution_policy.h>
#include <embb/mtapi/job.h> #include <embb/mtapi/job.h>
#include <embb/mtapi/action.h> #include <embb/mtapi/action.h>
#include <embb/mtapi/group.h> #include <embb/mtapi/group.h>
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#define EMBB_MTAPI_NODE_H_ #define EMBB_MTAPI_NODE_H_
#include <embb/base/memory_allocation.h> #include <embb/base/memory_allocation.h>
#include <embb/base/function.h>
#include <embb/mtapi/c/mtapi.h> #include <embb/mtapi/c/mtapi.h>
#include <embb/mtapi/status_exception.h> #include <embb/mtapi/status_exception.h>
#include <embb/mtapi/node_attributes.h> #include <embb/mtapi/node_attributes.h>
...@@ -37,6 +38,13 @@ ...@@ -37,6 +38,13 @@
#include <embb/mtapi/task_attributes.h> #include <embb/mtapi/task_attributes.h>
#include <embb/mtapi/job.h> #include <embb/mtapi/job.h>
#include <embb/mtapi/action.h> #include <embb/mtapi/action.h>
#include <embb/mtapi/task_context.h>
#ifdef GetJob
#undef GetJob
#endif
#define EMBB_MTAPI_FUNCTION_JOB_ID 2
namespace embb { namespace embb {
...@@ -55,6 +63,8 @@ namespace mtapi { ...@@ -55,6 +63,8 @@ namespace mtapi {
*/ */
class Node { class Node {
public: public:
typedef embb::base::Function<void, TaskContext &> SMPFunction;
/** /**
* Initializes the runtime singleton using default values: * Initializes the runtime singleton using default values:
* - all available cores will be used * - all available cores will be used
...@@ -156,6 +166,27 @@ class Node { ...@@ -156,6 +166,27 @@ class Node {
return task_limit_; return task_limit_;
} }
Task Start(
SMPFunction const & func
) {
Job job = GetJob(EMBB_MTAPI_FUNCTION_JOB_ID);
void * res = NULL;
return Start(
job, embb::base::Allocation::New<SMPFunction>(func), res);
}
Task Start(
SMPFunction const & func,
ExecutionPolicy const & policy
) {
Job job = GetJob(EMBB_MTAPI_FUNCTION_JOB_ID);
void * res = NULL;
TaskAttributes task_attr;
task_attr.SetPolicy(policy);
return Start(
job, embb::base::Allocation::New<SMPFunction>(func), res, task_attr);
}
/** /**
* Starts a new Task. * Starts a new Task.
* *
...@@ -236,10 +267,6 @@ class Node { ...@@ -236,10 +267,6 @@ class Node {
MTAPI_DEFAULT_TASK_ATTRIBUTES); MTAPI_DEFAULT_TASK_ATTRIBUTES);
} }
#ifdef GetJob
#undef GetJob
#endif
Job GetJob(mtapi_job_id_t job_id) { Job GetJob(mtapi_job_id_t job_id) {
return Job(job_id, domain_id_); return Job(job_id, domain_id_);
} }
...@@ -397,6 +424,21 @@ class Node { ...@@ -397,6 +424,21 @@ class Node {
return Task(task_hndl); return Task(task_hndl);
} }
static void ActionFunction(
const void* args,
mtapi_size_t /*args_size*/,
void* /*result_buffer*/,
mtapi_size_t /*result_buffer_size*/,
const void* /*node_local_data*/,
mtapi_size_t /*node_local_data_size*/,
mtapi_task_context_t * context) {
TaskContext task_context(context);
embb::base::Function<void, TaskContext &> * func =
reinterpret_cast<embb::base::Function<void, TaskContext &>*>(const_cast<void*>(args));
(*func)(task_context);
embb::base::Allocation::Delete(func);
}
static embb::mtapi::Node * node_instance_; static embb::mtapi::Node * node_instance_;
mtapi_domain_t domain_id_; mtapi_domain_t domain_id_;
...@@ -405,6 +447,7 @@ class Node { ...@@ -405,6 +447,7 @@ class Node {
mtapi_uint_t queue_count_; mtapi_uint_t queue_count_;
mtapi_uint_t group_count_; mtapi_uint_t group_count_;
mtapi_uint_t task_limit_; mtapi_uint_t task_limit_;
Action function_action_;
}; };
} // namespace mtapi } // namespace mtapi
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <embb/mtapi/c/mtapi.h> #include <embb/mtapi/c/mtapi.h>
#include <embb/mtapi/internal/check_status.h> #include <embb/mtapi/internal/check_status.h>
#include <embb/mtapi/execution_policy.h>
namespace embb { namespace embb {
namespace mtapi { namespace mtapi {
...@@ -86,6 +87,31 @@ class TaskAttributes { ...@@ -86,6 +87,31 @@ class TaskAttributes {
} }
/** /**
* Sets the affinity of a Task.
* The affinity influences on which worker the Task will be executed.
*
* \returns Reference to this object.
* \notthreadsafe
*/
TaskAttributes & SetAffinity(
mtapi_affinity_t affinity /**< The affinity to set. */
) {
mtapi_status_t status;
mtapi_taskattr_set(&attributes_, MTAPI_TASK_AFFINITY,
&affinity, sizeof(affinity), &status);
internal::CheckStatus(status);
return *this;
}
TaskAttributes & SetPolicy(
ExecutionPolicy const & policy
) {
SetPriority(policy.GetPriority());
SetAffinity(policy.GetAffinity());
return *this;
}
/**
* Sets the number of instances in a Task. * Sets the number of instances in a Task.
* The Task will be launched \c instances times. In the action function, * The Task will be launched \c instances times. In the action function,
* the number of instances and the current instance can be queried from * the number of instances and the current instance can be queried from
......
...@@ -109,7 +109,7 @@ unsigned int ExecutionPolicy::GetCoreCount() const { ...@@ -109,7 +109,7 @@ unsigned int ExecutionPolicy::GetCoreCount() const {
return embb_bitset_count(&affinity_); return embb_bitset_count(&affinity_);
} }
const mtapi_affinity_t &ExecutionPolicy::GetAffinity() const { mtapi_affinity_t ExecutionPolicy::GetAffinity() const {
return affinity_; return affinity_;
} }
......
...@@ -41,11 +41,13 @@ void Node::Initialize( ...@@ -41,11 +41,13 @@ void Node::Initialize(
if (IsInitialized()) { if (IsInitialized()) {
EMBB_THROW(StatusException, EMBB_THROW(StatusException,
"MTAPI: node was already initialized."); "MTAPI: node was already initialized.");
} } else {
else {
NodeAttributes attributes; // default attributes NodeAttributes attributes; // default attributes
node_instance_ = embb::base::Allocation::New<Node>( node_instance_ = embb::base::Allocation::New<Node>(
domain_id, node_id, attributes); domain_id, node_id, attributes);
Job job = node_instance_->GetJob(EMBB_MTAPI_FUNCTION_JOB_ID);
node_instance_->function_action_ =
node_instance_->CreateAction(EMBB_MTAPI_FUNCTION_JOB_ID, ActionFunction);
} }
} }
...@@ -57,8 +59,7 @@ void Node::Initialize( ...@@ -57,8 +59,7 @@ void Node::Initialize(
if (IsInitialized()) { if (IsInitialized()) {
EMBB_THROW(StatusException, EMBB_THROW(StatusException,
"MTAPI: node was already initialized."); "MTAPI: node was already initialized.");
} } else {
else {
node_instance_ = embb::base::Allocation::New<Node>( node_instance_ = embb::base::Allocation::New<Node>(
domain_id, node_id, attributes); domain_id, node_id, attributes);
} }
...@@ -79,8 +80,7 @@ Node & Node::GetInstance() { ...@@ -79,8 +80,7 @@ Node & Node::GetInstance() {
#else #else
if (IsInitialized()) { if (IsInitialized()) {
return *node_instance_; return *node_instance_;
} } else {
else {
EMBB_THROW(StatusException, EMBB_THROW(StatusException,
"MTAPI: node is not initialized."); "MTAPI: node is not initialized.");
} }
...@@ -89,11 +89,11 @@ Node & Node::GetInstance() { ...@@ -89,11 +89,11 @@ Node & Node::GetInstance() {
void Node::Finalize() { void Node::Finalize() {
if (IsInitialized()) { if (IsInitialized()) {
node_instance_->function_action_.Delete();
mtapi_finalize(MTAPI_NULL); mtapi_finalize(MTAPI_NULL);
embb::base::Allocation::Delete(node_instance_); embb::base::Allocation::Delete(node_instance_);
node_instance_ = NULL; node_instance_ = NULL;
} } else {
else {
EMBB_THROW(StatusException, EMBB_THROW(StatusException,
"MTAPI: node is not initialized."); "MTAPI: node is not initialized.");
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment