// // Copyright (C) 2014 Jens Korinth, TU Darmstadt // // This file is part of ThreadPoolComposer (TPC). // // ThreadPoolComposer is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // ThreadPoolComposer is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with ThreadPoolComposer. If not, see . // //! @file tpc_api.h //! @brief ThreadPoolComposer API for hardware threadpool integration. //! Low-level API to interface hardware accelerators programmed with //! ThreadPoolComposer support. //! @authors J. Korinth, TU Darmstadt (jk@esa.cs.tu-darmstadt.de) //! @authors D. de la Chevallerie, TU Darmstadt (dc@esa.cs.tu-darmstadt.de) //! @version 1.2 //! @copyright Copyright 2014, 2015 J. Korinth, TU Darmstadt //! //! This file is part of ThreadPoolComposer (TPC). //! //! ThreadPoolComposer is free software: you can redistribute it //! and/or modify it under the terms of the GNU Lesser General //! Public License as published by the Free Software Foundation, //! either version 3 of the License, or (at your option) any later //! version. //! //! ThreadPoolComposer is distributed in the hope that it will be //! useful, but WITHOUT ANY WARRANTY; without even the implied //! warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. //! See the GNU Lesser General Public License for more details. //! //! You should have received a copy of the GNU Lesser General Public //! License along with ThreadPoolComposer. If not, see //! . //! @details ### Change Log ### //! - Version 1.2 (jk) //! + removed 'rpr' namespace //! - Version 1.1 (jk) //! + added API version constant and automatic checks to guarantee //! that the user is using the right header for the lib //! (necessary due to incompatible changes between versions) //! + added consistent flags to all calls for future use //! - Version 1.0 (jk, dc) //! + initial prototype version //! //! @todo device enumeration? //! #ifndef __TPC_API_H__ #define __TPC_API_H__ #ifdef __cplusplus #include #include #include namespace rpr { // reintroduced REPARA namespace namespace tpc { extern "C" { #else #include #include #include #endif /* __cplusplus */ /** @defgroup types Types * @{ **/ /** General purpose result type **/ typedef enum { /** Indicates unspecific failure, should not be used. **/ TPC_FAILURE = 0, /** Indicates successful operation. **/ TPC_SUCCESS } tpc_res_t; /** FPGA context; opaque forward decl. **/ typedef struct tpc_ctx tpc_ctx_t; /** Device context; opaque forward decl. **/ typedef struct tpc_dev_ctx tpc_dev_ctx_t; /** Identifies a FPGA device (currently only one). **/ typedef uint32_t tpc_dev_id_t; /** * Identifies a 'processing element' on the device, i.e., a rpr::kernel * occurrence. * Note: A function can have more than one instantiation in a bitstream. **/ typedef uint32_t tpc_func_id_t; /** Identifies jobs, i.e,, sets of arguments for a kernel execution. **/ typedef uint32_t tpc_job_id_t; /** Device memory location handle (opaque). **/ typedef uint32_t tpc_handle_t; /** Flags for device creation (implementation defined). **/ typedef enum { /** no flags **/ TPC_DEVICE_CREATE_FLAGS_NONE = 0 } tpc_device_create_flag_t; /** Flags for memory allocation (implementation defined). **/ typedef enum { /** no flags **/ TPC_DEVICE_ALLOC_FLAGS_NONE = 0 } tpc_device_alloc_flag_t; /** Flags for bitstream loading (implementation defined). **/ typedef enum { /** no flags **/ TPC_LOAD_BITSTREAM_FLAGS_NONE = 0 } tpc_load_bitstream_flag_t; /** Flags for calls to tpc_device_copy_to and tpc_device_copy_from. **/ typedef enum { /** no flags **/ TPC_DEVICE_COPY_FLAGS_NONE = 0, /** wait until transfer is finished (default) **/ TPC_DEVICE_COPY_BLOCKING = 0, /** return immediately after transfer was scheduled **/ TPC_DEVICE_COPY_NONBLOCKING = 1, } tpc_device_copy_flag_t; /** Flags for calls to tpc_device_acquire_job_id. **/ typedef enum { /** no flags **/ TPC_DEVICE_ACQUIRE_JOB_ID_FLAGS_NONE = 0, /** wait until id becomes available (default) **/ TPC_DEVICE_ACQUIRE_JOB_ID_BLOCKING = 0, /** fail if id is not immediately available, do not wait **/ TPC_DEVICE_ACQUIRE_JOB_ID_NONBLOCKING = 1, } tpc_device_acquire_job_id_flag_t; /** Flags for calls to tpc_device_job_launch. **/ typedef enum { /** no flags **/ TPC_DEVICE_JOB_LAUNCH_FLAGS_NONE = 0, /** launch and wait until job is finished (default) **/ TPC_DEVICE_JOB_LAUNCH_BLOCKING = 0, /** return immediately after job is scheduled **/ TPC_DEVICE_JOB_LAUNCH_NONBLOCKING = 1, } tpc_device_job_launch_flag_t; /** @} **/ /** @defgroup version Version Info * @{ **/ #define TPC_API_VERSION "1.2" /** * Returns the version string of the library. * @return string with version, e.g. "1.1" **/ const char *const tpc_version(); /** * Checks if runtime version matches header. Should be called at init time. * @return TPC_SUCCESS if version matches, an error code otherwise **/ tpc_res_t tpc_check_version(const char *const version); /** @} **/ /** @defgroup aux Auxiliary Functions * @{ **/ /** * Returns a pointer to a string describing the error code in res. * @param res error code * @return pointer to description of error **/ const char *const tpc_strerror(tpc_res_t const res); /** @} **/ /** @defgroup devmgmt Device Management * @{ **/ /** * Global initialization: Setup a context for management of threadpool devices. * Should not be called directly; @see tpc_init. * @param version version string of expected TPC API version * @param pctx pointer to context pointer (will be set on success) * @return TPC_SUCCESS if successful, an error code otherwise **/ tpc_res_t _tpc_init(const char *const version, tpc_ctx_t **pctx); /** * Global initialization: Setup a context for management of threadpool devices. * @param pctx pointer to context pointer (will be set on success) * @return TPC_SUCCESS if successful, an error code otherwise **/ inline static tpc_res_t tpc_init(tpc_ctx_t **pctx) { return _tpc_init(TPC_API_VERSION, pctx); } /** * Global destructor: perform global clean-up before exiting. * @param ctx pointer to global context **/ void tpc_deinit(tpc_ctx_t *ctx); /** * Device init; called once for exclusive acceess to given device. * @param ctx pointer to global context * @param dev_id device id * @param pdev_ctx pointer to device context pointer (will be set * on success) * @param flags device creation flags * @return TPC_SUCCESS if sucessful, an error code otherwise **/ tpc_res_t tpc_create_device(tpc_ctx_t *ctx, tpc_dev_id_t const dev_id, tpc_dev_ctx_t **pdev_ctx, tpc_device_create_flag_t const flags); /** * Device deinit: called once for each valid tpc_dev_ctx_t to release exclusive * access to the device and perform clean-up tasks. * @param ctx global context * @param dev_ctx device context **/ void tpc_destroy_device(tpc_ctx_t *ctx, tpc_dev_ctx_t *dev_ctx); /** * Returns the number of instances of function func_id in the currently * loaded bitstream. * @param dev_ctx device context * @param func_id function id * @return number of instances > 0 if function is instantiated in the bitstream, * 0 if function is unavailable **/ uint32_t tpc_device_func_instance_count(tpc_dev_ctx_t *dev_ctx, tpc_func_id_t const func_id); /** * Loads the bitstream from the given file to the device. * @param dev_ctx device context * @param filename bitstream file name * @param flags bitstream loading flags * @return TPC_SUCCESS if sucessful, TPC_FAILURE otherwise **/ tpc_res_t tpc_device_load_bitstream_from_file(tpc_dev_ctx_t *dev_ctx, char const *filename, tpc_load_bitstream_flag_t const flags); /** * Loads a bitstream to the given device. * @param dev_ctx device context * @param len size in bytes * @param data pointer to bitstream data * @param flags bitstream loading flags * @return TPC_SUCCESS if sucessful, TPC_FAILURE otherwise **/ tpc_res_t tpc_device_load_bitstream(tpc_dev_ctx_t *dev_ctx, size_t const len, void const *data, tpc_load_bitstream_flag_t const flags); /** @} **/ /** @defgroup data Data Management and Transfer * @{ **/ /** * Allocates a chunk of len bytes on the device. * @param dev_ctx device context * @param h output parameter to write the handle to * @param len size in bytes * @param flags device memory allocation flags * @return TPC_SUCCESS if successful, error code otherwise **/ tpc_res_t tpc_device_alloc(tpc_dev_ctx_t *dev_ctx, tpc_handle_t *handle, size_t const len, tpc_device_alloc_flag_t const flags); /** * Frees a previously allocated chunk of device memory. * @param dev_ctx device context * @param handle memory chunk handle returned by @see tpc_alloc * @param flags device memory allocation flags **/ void tpc_device_free(tpc_dev_ctx_t *dev_ctx, tpc_handle_t handle, tpc_device_alloc_flag_t const flags); /** * Copys memory from main memory to the FPGA device. * @param dev_ctx device context * @param src source address * @param dst destination device handle (prev. alloc'ed with tpc_alloc) * @param len number of bytes to copy * @param flags flags for copy operation, e.g., TPC_COPY_NONBLOCKING * @return TPC_SUCCESS if copy was successful, TPC_FAILURE otherwise **/ tpc_res_t tpc_device_copy_to(tpc_dev_ctx_t *dev_ctx, void const *src, tpc_handle_t dst, size_t len, tpc_device_copy_flag_t const flags); /** * Copys memory from FPGA device memory to main memory. * @param dev_ctx device context * @param src source device handle (prev. alloc'ed with tpc_alloc) * @param dst destination address * @param len number of bytes to copy * @param flags flags for copy operation, e.g., TPC_COPY_NONBLOCKING * @return TPC_SUCCESS if copy was successful, TPC_FAILURE otherwise **/ tpc_res_t tpc_device_copy_from(tpc_dev_ctx_t *dev_ctx, tpc_handle_t src, void *dst, size_t len, tpc_device_copy_flag_t const flags); /** @} **/ /** @defgroup exec Execution Control * @{ **/ /** * Obtains a job context to associate function parameters with, i.e., that can * be used in @see tpc_set_arg calls to set kernel arguments. * Note: May block until job context is available. * @param dev_ctx device context * @param func_id function id * @param flags or'ed flags for the call, @see tpc_device_acquire_job_id_flag_t * for options * @return job id > 0 if successful, 0 otherwise **/ tpc_job_id_t tpc_device_acquire_job_id(tpc_dev_ctx_t *dev_ctx, tpc_func_id_t const func_id, tpc_device_acquire_job_id_flag_t flags); /** * Releases a job id obtained via @see tpc_acquire_job_id. Does not affect * related handles alloc'ed via tpc_alloc, which must be release separately, * only release return value(s) of job. * @param dev_ctx device context * @param job_id job id to release **/ void tpc_device_release_job_id(tpc_dev_ctx_t *dev_ctx, tpc_job_id_t const job_id); /** * Launches the given job and releases its id (does not affect alloc'ed handles, * means only that kernel arguments can no longer be set using this id). * Blocks caller execution until kernel has finished. * @param dev_ctx device context * @param job_id job id * @param flags launch flags, e.g., TPC_DEVICE_JOB_LAUNCH_BLOCKING * @return TPC_SUCCESS if execution was successful and results can be * retrieved, TPC_FAILURE otherwise. **/ tpc_res_t tpc_device_job_launch(tpc_dev_ctx_t *dev_ctx, tpc_job_id_t const job_id, tpc_device_job_launch_flag_t const flags); /** * Sets the arg_idx'th argument of function func_id to arg_value. * @param dev_ctx device context * @param job_id job id * @param arg_idx argument number * @param arg_len length of arg_value in bytes (must be power of 4) * @param arg_value data to set argument to. * @return TPC_SUCCESS if successful, TPC_FAILURE otherwise. **/ tpc_res_t tpc_device_job_set_arg(tpc_dev_ctx_t *dev_ctx, tpc_job_id_t const job_id, uint32_t arg_idx, size_t const arg_len, void const *arg_value); /** * Gets the value of the arg_idx'th argument of function func_id. * @param dev_ctx device context * @param job_id job id * @param arg_idx argument number * @param arg_len length of arg_value in bytes (must be power of 4) * @param arg_value data to store argument in. * @return TPC_SUCCESS if successful, TPC_FAILURE otherwise. **/ tpc_res_t tpc_device_job_get_arg(tpc_dev_ctx_t *dev_ctx, tpc_job_id_t const job_id, uint32_t arg_idx, size_t const arg_len, void *arg_value); /** * Retrieves the return value of job with the given id to ret_value. * @param dev_ctx device context * @param job_id job id * @param ret_len size of return value in bytes (must be power of 4) * @param ret_value pointer to mem to write return value to * @return TPC_SUCCESS if sucessful, TPC_FAILURE otherwise. **/ tpc_res_t tpc_device_job_get_return(tpc_dev_ctx_t *dev_ctx, tpc_job_id_t const job_id, size_t const ret_len, void *ret_value); /** @} **/ #ifdef __cplusplus } /* extern "C" */ } /* namespace tpc */ } /* namespace rpr */ #endif /* __cplusplus */ #endif /* __TPC_API_H__ */ /* vim: set foldmarker=@{,@} foldlevel=0 foldmethod=marker : */