#pragma once #include #include #include #include #include #include #include namespace wfr { namespace wfs { /** * Base class for atomic activity implementations. * * Must be cast to type specific class to be able to access type specific information. * Currently implemented sub-classes: * x) PThreadActivityImplementation * x) OpenCLActivityImplementation * x) CUDAActivityImplementation **/ class AtomicActivityImplementation { // Static objects to guarantee unique implementation IDs. private: static std::atomic nextImplementationID; static wfr_id_t getNextImplementationID() { return nextImplementationID.fetch_add(1); } // Mutable properties that need to be accessed via getter-/setter-functions. protected: std::vector requiredCapabilities; utils::Properties properties; // Invariant properties that can be accessed directly. public: const wfr_id_t implementationID; const ActivityImplementationType implementationType; const std::string name; // Non-public functions. protected: AtomicActivityImplementation( ActivityImplementationType implementationType, const std::vector& capabilities, const utils::Properties& properties, const std::string& name) noexcept : requiredCapabilities(capabilities), properties(properties), implementationID(getNextImplementationID()), implementationType(implementationType), name(name) {} // Public functions. public: virtual ~AtomicActivityImplementation() noexcept {} /** * Returns a vector with capabilities required for execution of this implementation. **/ const std::vector& getRequiredCapabilities() const noexcept { return requiredCapabilities; } /** * Returns properties associated with this implementation. **/ const utils::Properties& getProperties() const noexcept { return properties; } /** * Helper function to ease cast operations. **/ template T& as() noexcept { return *static_cast(this); } /** * Const helper function to ease cast operations. **/ template const T& as() const noexcept { return *static_cast(this); } /* * Static factory functions for creating activity implementation objects. * * Returned objects need to be manually deleted (Using smartpointers here causes too much overhead). * AtomicActivityImplementation objects are usually passed to an AtomicActivityType object which manages the lifecycle. */ public: /** * Returns a new pthread implementation object. * * Do not add GenericCPU capability as it is already automatically added. **/ static AtomicActivityImplementation* PThread( const ExecutionHookFunc& executionFuncHook, const std::string& name = "", utils::PropertyList properties = {}, resource::RequiredCapabilityList capabilities = {} ) noexcept; /** * Returns a new OpenCL implementation object. * * Do not add OpenCL capability as it is already automatically added. **/ static AtomicActivityImplementation* OpenCL( const ExecutionHookFunc& executionFuncHook, const std::string& name = "", std::initializer_list minVersion = {0, 0}, std::initializer_list maxVersion = {0, 0}, utils::PropertyList properties = {}, resource::RequiredCapabilityList capabilities = {} ) noexcept; /** * Returns a new CUDA implementation object. **/ static AtomicActivityImplementation* CUDA( const ExecutionHookFunc& executionFuncHook, const std::string& name = "", std::initializer_list minVersion = {0, 0}, std::initializer_list maxVersion = {0, 0}, utils::PropertyList properties = {}, resource::RequiredCapabilityList capabilities = {} ) noexcept; }; } /* namespace wfs */ } /* namespace wfr */