#ifndef __USER_SENSE_API_LIB_H__ #define __USER_SENSE_API_LIB_H__ #include #include #include #include #include #include #include #include #include #define CL_TARGET_OPENCL_VERSION 120 #include class OptionParser; namespace smo { class ComponentThread; namespace compute { class ClBuffer; class ComputeDevice; } // namespace compute namespace stim_buff { /** * @brief Threading model descriptor for senseApi libraries. * * This structure provides senseApi libraries with access to the information and * resources they need to operate with SMO's threading model. */ struct SmoThreadingModelDesc { /** * @brief sh_ptr to ComponentThread for device-independent state mgt. * * This ComponentThread should be used by senseApis for state management * that's independent of any particular device or attachment spec. * SMO will usually pass in the Marionette thread here. * * State management that's tied to a particular attachment spec should be * done on the ComponentThread for the thread that SMO provided in the * attachDeviceReq call. */ std::shared_ptr componentThread; }; typedef std::function)> sal_mlo_attachDeviceReqCbFn; typedef std::function)> sal_mlo_detachDeviceReqCbFn; typedef int (sal_mlo_initializeIndFn)(void); typedef int (sal_mlo_finalizeIndFn)(void); typedef void (sal_mlo_attachDeviceReqFn)( const std::shared_ptr& desc, const std::shared_ptr& componentThread, Callback cb); typedef void (sal_mlo_detachDeviceReqFn)( const std::shared_ptr& desc, Callback cb); /** * @brief Hooks provided by Salmanoff to senseApi libraries. * This structure contains function pointers that senseApi libraries can use * to interact with Salmanoff's functionality, such as searching for commonLibs. */ struct SmoCallbacks { /** * @brief Search for a library in Salmanoff's search paths * @param libraryPath The relative filename of the library to search for * @return Optional containing the full path if found, nullopt if not found * * This function searches for the given library in the same search paths * that Salmanoff uses when loading senseApi libraries (user-specified * paths via -p option, current directory, and executable directory). */ std::optional (*searchForLibInSmoSearchPaths)( const std::string& libraryPath); /** * @brief Get the current ComponentThread instance * @return Shared pointer to the current ComponentThread * * This function provides access to the current ComponentThread instance, * equivalent to calling ComponentThread::getSelf(). */ std::shared_ptr (*ComponentThread_getSelf)(void); /** * @brief Get the OptionParser singleton instance * @return Reference to the OptionParser singleton * * This function provides access to the OptionParser singleton instance, * equivalent to calling OptionParser::getOptions(). */ OptionParser& (*OptionParser_getOptions)(void); /** * @brief Create a USE_HOST_PTR buffer on all OpenCL contexts * @param hostPtr Host pointer to the memory * @param size Size of the buffer in bytes * @param flags Additional OpenCL memory flags * @return Shared pointer to ClBuffer managing buffers on all devices */ std::shared_ptr (*ComputeManager_createUseHostPtrBuffer)( void* hostPtr, size_t size, cl_mem_flags flags); /** * @brief Release USE_HOST_PTR buffers from all contexts * @param buffer Shared pointer to ClBuffer to release */ void (*ComputeManager_releaseUseHostPtrBuffer)( std::shared_ptr buffer); /** * @brief Get a compute device * @return Shared pointer to ComputeDevice, or nullptr if no devices available */ std::shared_ptr (*ComputeManager_getDevice)(void); /** * @brief Release a compute device * @param device Shared pointer to ComputeDevice to release */ void (*ComputeManager_releaseDevice)( std::shared_ptr device); }; struct Sal_Mgmt_LibOps { /* When Salmanoff loads a stim buff API lib, it calls this function to initialize * the lib. When this returns, the lib should be ready to attach devices. */ sal_mlo_initializeIndFn *initializeInd; /* Salmanoff calls this to finalize the lib and free its internal * resources. When this returns, the lib should be ready to be unloaded. */ sal_mlo_finalizeIndFn *finalizeInd; /* Salmanoff calls this to attach a device to the lib. When it returns, the * device should be attached and ready to present its stimbuff. */ sal_mlo_attachDeviceReqFn *attachDeviceReq; // When this returns, the device should be detached. sal_mlo_detachDeviceReqFn *detachDeviceReq; static bool sanityCheck(const Sal_Mgmt_LibOps &ops) { if (!ops.initializeInd || !ops.finalizeInd || !ops.attachDeviceReq || !ops.detachDeviceReq) { return false; } return true; } }; /* Exported by all stim buff API Libraries to tell Salmanoff what API the lib uses * to connect to providers; and also to state which quale-iface APIs it exports. */ class StimBuffApiDesc { public: class ExportedQualeIfaceApiDesc { public: static bool sanityCheck(const ExportedQualeIfaceApiDesc &desc) { if (desc.name.empty()) { return false; } return true; } public: std::string name; }; public: std::string stringify() const { std::string result = "Name: " + name + "\n"; result += "Exported QualeIface APIs:\n"; for (const auto& api : exportedQualeIfaceApis) { result += " - " + api.name + "\n"; } return result; } static bool sanityCheck(const StimBuffApiDesc &desc) { if (desc.name.empty() || desc.exportedQualeIfaceApis.empty()) { return false; } for (const auto& api : desc.exportedQualeIfaceApis) { if (!ExportedQualeIfaceApiDesc::sanityCheck(api)) { return false; } } return Sal_Mgmt_LibOps::sanityCheck(desc.sal_mgmt_libOps); } std::string name; // These are the quale-iface APIs this lib exports. std::vector exportedQualeIfaceApis; Sal_Mgmt_LibOps sal_mgmt_libOps; }; #define SMO_GET_STIM_BUFF_API_DESC_FN_NAME getStimBuffApiDesc #define SMO_GET_STIM_BUFF_API_DESC_FN_NAME_STR \ SMO_QUOTE(SMO_GET_STIM_BUFF_API_DESC_FN_NAME) #define SMO_GET_STIM_BUFF_API_DESC_FN_TYPEDEF \ SMO_CONCAT(SMO_GET_STIM_BUFF_API_DESC_FN_NAME, Fn) /* Every Stim Buff API library must define a global instance of this * function. Salmanoff will search for it and invoke it via dlsym(). * * The function must return a StimBuffApiDesc struct that Smo will tell * Smo what quale-iface APIs can be used with it & what APIs it exports. * The StimBuffApiDesc struct also gives Smo pointers to API functions * to invoke for communication between Smo and the library. * * The SmoCallbacks parameter provides the library with access to * Salmanoff's hooks. * The SmoThreadingModelDesc parameter provides the library with access to * the io_service for network operations and event handling. */ typedef const StimBuffApiDesc &(SMO_GET_STIM_BUFF_API_DESC_FN_TYPEDEF)( const SmoCallbacks& callbacks, const SmoThreadingModelDesc& threadingModel); } // namespace stim_buff } // namespace smo #endif // __USER_SENSE_API_LIB_H__