#ifdef MAXCOMPILER_VERSION_INFO #define MAXCOMPILER_VERSION_INFO_PRESENT 1 #define MAXFILE_MAXCOMPILER_VERSION_YEAR 2018 #define MAXFILE_MAXCOMPILER_VERSION_NUM 3 #define MAXFILE_MAXCOMPILER_VERSION_POINT 1 #define MAXFILE_MAXCOMPILER_VERSION_PATCH "" #define MAXFILE_MAXCOMPILER_VERSION_REV "b189b8e" #define MAXFILE_MAXCOMPILER_VERSION_RELEASE_DATE "2019-01-09" #define MAXFILE_MAXCOMPILER_VERSION_RELEASE_MODE true #endif #ifdef MAXFILE_BUILD_INFO #define MAXFILE_BUILD_INFO_PRESENT 1 #define MAXFILE_BUILD_NAME "StreamFMA" #define MAXFILE_BUILD_DIR "/mnt/beegfs/home/jusers/makni1/jumax/makni3/starpu.git/tests/./StreamFMA_MAX5C_DFE_SIM" #define MAXFILE_BUILD_DATE 20191029 #define MAXFILE_BUILD_REV 1 #endif #ifdef PARAM #define PARAM_PRESENT 1 PARAM(DYNAMIC_CLOCKS_ENABLED, 0) PARAM(APP_ID, 0) PARAM(REV_ID, 0) PARAM(CHAIN_LENGTH, 36) PARAM(IS_SIMULATION, 1) PARAM(MEC_SUPPORTED, 1) PARAM(PCIE_SLAVE_STREAMING, 0) PARAM(PCIE_ALIGNMENT, 16) PARAM(NUM_IFPGA_LINKS, 0) #endif #ifdef STRING_PARAM #define STRING_PARAM_PRESENT 1 STRING_PARAM(BOARD_MODEL, "MAX5_LIMA") #endif #ifdef INCLUDE_GENERATED_CPP_HEADERS #include "StreamFMAKernel.h" #endif #ifdef ENGINE_PARAMETERS #define ENGINE_PARAMETERS_PRESENT 1 ENGINE_PARAMETERS(DFEModel, DFEMODEL, MAIA) ENGINE_PARAMETERS(maxFileName, STRING, "StreamFMA") ENGINE_PARAMETERS(target, ENUM, DFE_SIM) ENGINE_PARAMETERS(enableMPCX, BOOL, false) ENGINE_PARAMETERS(MPPRStartCT, INT, 1) ENGINE_PARAMETERS(MPPREndCT, INT, 1) ENGINE_PARAMETERS(MPPRThreads, INT, 1) ENGINE_PARAMETERS(MPPRRetryThreshold, INT, 0) #endif #ifdef MANAGER_NODE #define MANAGER_NODE_PRESENT 1 MANAGER_NODE(StreamFMAKernel, Kernel) MANAGER_NODE(a, PCIe_From_Host) MANAGER_NODE(b, PCIe_From_Host) MANAGER_NODE(output, PCIe_To_Host) MANAGER_NODE(Stream_1, DualAspectMux) MANAGER_NODE(Stream_4, DualAspectMux) MANAGER_NODE(Stream_8, DualAspectReg) MANAGER_NODE(Stream_21, StreamPullPushAdapter) MANAGER_NODE(Stream_11, Fifo) MANAGER_NODE(Stream_15, Fifo) MANAGER_NODE(Stream_13, Fifo) MANAGER_NODE(Stream_17, Fifo) MANAGER_NODE(Stream_19, Fifo) #endif #ifdef MANAGER_NODE_IO #define MANAGER_NODE_IO_PRESENT 1 MANAGER_NODE_IO(StreamFMAKernel, a, IN, STREAM, 32, PULL) MANAGER_NODE_IO(StreamFMAKernel, b, IN, STREAM, 32, PULL) MANAGER_NODE_IO(StreamFMAKernel, output, OUT, STREAM, 32, PUSH) MANAGER_NODE_IO(a, a, OUT, PCIE, 128, PUSH) MANAGER_NODE_IO(b, b, OUT, PCIE, 128, PUSH) MANAGER_NODE_IO(output, output, IN, PCIE, 128, PUSH) MANAGER_NODE_IO(Stream_1, input, IN, PCIE, 128, PULL) MANAGER_NODE_IO(Stream_1, output, OUT, PCIE, 32, PUSH) MANAGER_NODE_IO(Stream_4, input, IN, PCIE, 128, PULL) MANAGER_NODE_IO(Stream_4, output, OUT, PCIE, 32, PUSH) MANAGER_NODE_IO(Stream_8, input, IN, PCIE, 32, PULL) MANAGER_NODE_IO(Stream_8, output, OUT, PCIE, 128, PULL) MANAGER_NODE_IO(Stream_21, input, IN, PCIE, 128, PULL) MANAGER_NODE_IO(Stream_21, output, OUT, PCIE, 128, PUSH) MANAGER_NODE_IO(Stream_11, input, IN, PCIE, 128, PUSH) MANAGER_NODE_IO(Stream_11, output, OUT, PCIE, 128, PULL) MANAGER_NODE_IO(Stream_15, input, IN, PCIE, 128, PUSH) MANAGER_NODE_IO(Stream_15, output, OUT, PCIE, 128, PULL) MANAGER_NODE_IO(Stream_13, input, IN, PCIE, 32, PUSH) MANAGER_NODE_IO(Stream_13, output, OUT, STREAM, 32, PULL) MANAGER_NODE_IO(Stream_17, input, IN, PCIE, 32, PUSH) MANAGER_NODE_IO(Stream_17, output, OUT, STREAM, 32, PULL) MANAGER_NODE_IO(Stream_19, input, IN, STREAM, 32, PUSH) MANAGER_NODE_IO(Stream_19, output, OUT, PCIE, 32, PULL) #endif #ifdef MANAGER_STREAM #define MANAGER_STREAM_PRESENT 1 MANAGER_STREAM(a, a, Stream_11, input, 128) MANAGER_STREAM(b, b, Stream_15, input, 128) MANAGER_STREAM(StreamFMAKernel, output, Stream_19, input, 32) MANAGER_STREAM(Stream_1, output, Stream_13, input, 32) MANAGER_STREAM(Stream_4, output, Stream_17, input, 32) MANAGER_STREAM(Stream_8, output, Stream_21, input, 128) MANAGER_STREAM(Stream_21, output, output, output, 128) MANAGER_STREAM(Stream_11, output, Stream_1, input, 128) MANAGER_STREAM(Stream_15, output, Stream_4, input, 128) MANAGER_STREAM(Stream_13, output, StreamFMAKernel, a, 32) MANAGER_STREAM(Stream_17, output, StreamFMAKernel, b, 32) MANAGER_STREAM(Stream_19, output, Stream_8, input, 32) #endif #ifdef MANAGER_NODE_STACK_TRACE #define MANAGER_NODE_STACK_TRACE_PRESENT 1 MANAGER_NODE_STACK_TRACE(StreamFMAKernel, "com.maxeler.platform.max5.manager.Max5ManagerBase.addKernel(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") MANAGER_NODE_STACK_TRACE(a, "com.maxeler.platform.max5.manager.Max5ManagerBase.addStreamFromCPU(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:14)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") MANAGER_NODE_STACK_TRACE(b, "com.maxeler.platform.max5.manager.Max5ManagerBase.addStreamFromCPU(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:15)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") MANAGER_NODE_STACK_TRACE(output, "com.maxeler.platform.max5.manager.Max5ManagerBase.addStreamToCPU(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:16)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") MANAGER_NODE_STACK_TRACE(Stream_1, "com.maxeler.platform.max5.manager.Max5ManagerBase.build(Unknown Source)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:21)\n") MANAGER_NODE_STACK_TRACE(Stream_4, "com.maxeler.platform.max5.manager.Max5ManagerBase.build(Unknown Source)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:21)\n") MANAGER_NODE_STACK_TRACE(Stream_8, "com.maxeler.platform.max5.manager.Max5ManagerBase.build(Unknown Source)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:21)\n") MANAGER_NODE_STACK_TRACE(Stream_21, "com.maxeler.platform.max5.manager.Max5ManagerBase.build(Unknown Source)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:21)\n") MANAGER_NODE_STACK_TRACE(Stream_11, "com.maxeler.platform.max5.manager.Max5ManagerBase.build(Unknown Source)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:21)\n") MANAGER_NODE_STACK_TRACE(Stream_15, "com.maxeler.platform.max5.manager.Max5ManagerBase.build(Unknown Source)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:21)\n") MANAGER_NODE_STACK_TRACE(Stream_13, "com.maxeler.platform.max5.manager.Max5ManagerBase.build(Unknown Source)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:21)\n") MANAGER_NODE_STACK_TRACE(Stream_17, "com.maxeler.platform.max5.manager.Max5ManagerBase.build(Unknown Source)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:21)\n") MANAGER_NODE_STACK_TRACE(Stream_19, "com.maxeler.platform.max5.manager.Max5ManagerBase.build(Unknown Source)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:21)\n") #endif #ifdef MANAGER_NODE_PROPERTY #define MANAGER_NODE_PROPERTY_PRESENT 1 MANAGER_NODE_PROPERTY(StreamFMAKernel, control_pipelining_depth, 2) #endif #ifdef KERNEL_CORE #define KERNEL_CORE_PRESENT 1 KERNEL_CORE(StreamFMAKernel) #endif #ifdef KERNEL_HOST_CONTROLLED #define KERNEL_HOST_CONTROLLED_PRESENT 1 KERNEL_HOST_CONTROLLED(StreamFMAKernel, StreamFMAKernel) #endif #ifdef DEBUG_INPUT_BITS #define DEBUG_INPUT_BITS_PRESENT 1 DEBUG_INPUT_BITS(StreamFMAKernel, a, 0) DEBUG_INPUT_BITS(StreamFMAKernel, b, 1) #endif #ifdef DEBUG_OUTPUT_BITS #define DEBUG_OUTPUT_BITS_PRESENT 1 DEBUG_OUTPUT_BITS(StreamFMAKernel, output, 0) #endif #ifdef MANAGER_NODE_CPP_SIM_MODEL_CTOR #define MANAGER_NODE_CPP_SIM_MODEL_CTOR_PRESENT 1 MANAGER_NODE_CPP_SIM_MODEL_CTOR(b, PCIePushSourceSync16, "b") MANAGER_NODE_CPP_SIM_MODEL_CTOR(a, PCIePushSourceSync16, "a") MANAGER_NODE_CPP_SIM_MODEL_CTOR(Stream_15, FifoPushToPullSync, "Stream_15", false, 512, 128) MANAGER_NODE_CPP_SIM_MODEL_CTOR(Stream_11, FifoPushToPullSync, "Stream_11", false, 512, 128) MANAGER_NODE_CPP_SIM_MODEL_CTOR(Stream_1, DualAspectMuxSync, "Stream_1", 32, 4) MANAGER_NODE_CPP_SIM_MODEL_CTOR(Stream_4, DualAspectMuxSync, "Stream_4", 32, 4) MANAGER_NODE_CPP_SIM_MODEL_CTOR(Stream_17, FifoPushToPullSync, "Stream_17", false, 512, 32) MANAGER_NODE_CPP_SIM_MODEL_CTOR(Stream_13, FifoPushToPullSync, "Stream_13", false, 512, 32) MANAGER_NODE_CPP_SIM_MODEL_CTOR(StreamFMAKernel, StreamFMAKernel, "StreamFMAKernel") MANAGER_NODE_CPP_SIM_MODEL_CTOR(Stream_19, FifoPushToPullSync, "Stream_19", false, 512, 32) MANAGER_NODE_CPP_SIM_MODEL_CTOR(Stream_8, DualAspectRegSync, "Stream_8", 32, 4) MANAGER_NODE_CPP_SIM_MODEL_CTOR(Stream_21, PullToPushAdapterSync, "Stream_21") MANAGER_NODE_CPP_SIM_MODEL_CTOR(output, PCIePushSinkSync16, "output") MANAGER_NODE_CPP_SIM_MODEL_CTOR(CapabilityReg, CapRegs, "CapabilityReg", 0, 2, 1, 0, 0, 0, 0, 0, 36) MANAGER_NODE_CPP_SIM_MODEL_CTOR(ifpga, IFPGARegs) MANAGER_NODE_CPP_SIM_MODEL_CTOR(sfa, SFARegs) MANAGER_NODE_CPP_SIM_MODEL_CTOR(ChecksumMemory, ChecksumMem, "ChecksumMemory", "ac5fbbbe6e4b46179c07a7a26c8647de7cec6bb27a42f5ac58fd3d986dbdfa72") #endif #ifdef MANAGER_NODE_CPP_SIM_MODEL_SETUP #define MANAGER_NODE_CPP_SIM_MODEL_SETUP_PRESENT 1 MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_ctld_almost_empty, 2, 0) MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_ctld_done, 2, 0) MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_ctld_empty, 2, 0) MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_ctld_read, 2, 0) MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_ctld_read_pipe_dbg, 6, 0) MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_ctld_request, 2, 0) MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_done_out, 1, 0) MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_fill_level, 4, 0) MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_flush_level, 4, 0) MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_flush_start, 1, 0) MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_flush_start_level, 4, 0) MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_flushing, 1, 0) MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_full_level, 4, 0) MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_out_stall, 1, 0) MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_out_valid, 1, 0) MANAGER_NODE_CPP_SIM_MODEL_SETUP(StreamFMAKernel, addDebugRegister, reg_dbg_stall_vector, 1, 0) #endif #ifdef PCIE_STREAM #define PCIE_STREAM_PRESENT 1 PCIE_STREAM(b, STREAM_FROM_HOST, 0) PCIE_STREAM(a, STREAM_FROM_HOST, 1) PCIE_STREAM(output, STREAM_TO_HOST, 0) #endif #ifdef REG #define REG_PRESENT 1 REG(StreamFMAKernel.io_a_force_disabled, 0x0, 1, hwOffsetFix(1, 0, UNSIGNED)) REG(StreamFMAKernel.io_b_force_disabled, 0x1, 1, hwOffsetFix(1, 0, UNSIGNED)) REG(StreamFMAKernel.io_output_force_disabled, 0x2, 1, hwOffsetFix(1, 0, UNSIGNED)) REG(StreamFMAKernel.run_cycle_count, 0x3, 6, hwOffsetFix(48, 0, UNSIGNED)) REG(StreamFMAKernel.current_run_cycle_count, 0x9, 6, hwOffsetFix(48, 0, UNSIGNED)) REG(StreamFMAKernel.dbg_ctld_almost_empty, 0xf, 1, hwBits(2)) REG(StreamFMAKernel.dbg_ctld_done, 0x10, 1, hwBits(2)) REG(StreamFMAKernel.dbg_ctld_empty, 0x11, 1, hwBits(2)) REG(StreamFMAKernel.dbg_ctld_read, 0x12, 1, hwBits(2)) REG(StreamFMAKernel.dbg_ctld_read_pipe_dbg, 0x13, 1, hwBits(6)) REG(StreamFMAKernel.dbg_ctld_request, 0x14, 1, hwBits(2)) REG(StreamFMAKernel.dbg_done_out, 0x15, 1, hwBits(1)) REG(StreamFMAKernel.dbg_fill_level, 0x16, 1, hwBits(4)) REG(StreamFMAKernel.dbg_flush_level, 0x17, 1, hwBits(4)) REG(StreamFMAKernel.dbg_flush_start, 0x18, 1, hwBits(1)) REG(StreamFMAKernel.dbg_flush_start_level, 0x19, 1, hwBits(4)) REG(StreamFMAKernel.dbg_flushing, 0x1a, 1, hwBits(1)) REG(StreamFMAKernel.dbg_full_level, 0x1b, 1, hwBits(4)) REG(StreamFMAKernel.dbg_out_stall, 0x1c, 1, hwBits(1)) REG(StreamFMAKernel.dbg_out_valid, 0x1d, 1, hwBits(1)) REG(StreamFMAKernel.dbg_stall_vector, 0x1e, 1, hwBits(1)) REG(ifpga.ifpga_ctrl, 0x1f, 1, hwBits(8)) REG(SignalForwardingAdapter.SFA_FORWARD_EN, 0x20, 4, hwBits(32)) #endif #ifdef REG_V2 #define REG_V2_PRESENT 1 REG_V2(StreamFMAKernel.io_a_force_disabled, 0x0, 1, hwOffsetFix(1, 0, UNSIGNED), HOST_WRITE_ONLY, true) REG_V2(StreamFMAKernel.io_b_force_disabled, 0x1, 1, hwOffsetFix(1, 0, UNSIGNED), HOST_WRITE_ONLY, true) REG_V2(StreamFMAKernel.io_output_force_disabled, 0x2, 1, hwOffsetFix(1, 0, UNSIGNED), HOST_WRITE_ONLY, true) REG_V2(StreamFMAKernel.run_cycle_count, 0x3, 6, hwOffsetFix(48, 0, UNSIGNED), HOST_WRITE_ONLY, false) REG_V2(StreamFMAKernel.current_run_cycle_count, 0x9, 6, hwOffsetFix(48, 0, UNSIGNED), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_ctld_almost_empty, 0xf, 1, hwBits(2), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_ctld_done, 0x10, 1, hwBits(2), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_ctld_empty, 0x11, 1, hwBits(2), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_ctld_read, 0x12, 1, hwBits(2), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_ctld_read_pipe_dbg, 0x13, 1, hwBits(6), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_ctld_request, 0x14, 1, hwBits(2), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_done_out, 0x15, 1, hwBits(1), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_fill_level, 0x16, 1, hwBits(4), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_flush_level, 0x17, 1, hwBits(4), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_flush_start, 0x18, 1, hwBits(1), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_flush_start_level, 0x19, 1, hwBits(4), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_flushing, 0x1a, 1, hwBits(1), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_full_level, 0x1b, 1, hwBits(4), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_out_stall, 0x1c, 1, hwBits(1), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_out_valid, 0x1d, 1, hwBits(1), HOST_READ_ONLY, false) REG_V2(StreamFMAKernel.dbg_stall_vector, 0x1e, 1, hwBits(1), HOST_READ_ONLY, false) REG_V2(ifpga.ifpga_ctrl, 0x1f, 1, hwBits(8), HOST_READ_WRITE, false) REG_V2(SignalForwardingAdapter.SFA_FORWARD_EN, 0x20, 4, hwBits(32), HOST_READ_WRITE, false) #endif #ifdef CHECKSUM #define CHECKSUM_PRESENT 1 CHECKSUM("ac5fbbbe6e4b46179c07a7a26c8647de7cec6bb27a42f5ac58fd3d986dbdfa72") #endif #ifdef CAPABILITY #define CAPABILITY_PRESENT 1 CAPABILITY(LIMAREV, LIMAREVA) CAPABILITY(LIMARAM, DDR4_48GB) CAPABILITY(LIMAFPGA, xcVU9P_FLGB2104_2_E) #endif #ifdef DEFINE_DESIGN_NAME #define DESIGN_NAME StreamFMA #endif /* DEFINE_DESIGN_NAME */ #ifndef SLIC_NO_DECLARATIONS /**\file */ #ifndef SLIC_DECLARATIONS_StreamFMA_H #define SLIC_DECLARATIONS_StreamFMA_H #include "MaxSLiCInterface.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define StreamFMA_DYNAMIC_CLOCKS_ENABLED (0) #define StreamFMA_PCIE_ALIGNMENT (16) /*----------------------------------------------------------------------------*/ /*---------------------------- Interface default -----------------------------*/ /*----------------------------------------------------------------------------*/ /** * \brief Basic static function for the interface 'default'. * * \param [in] ticks_StreamFMAKernel The number of ticks for which kernel "StreamFMAKernel" will run. * \param [in] instream_a Stream "a". * \param [in] instream_size_a The size of the stream instream_a in bytes. * \param [in] instream_b Stream "b". * \param [in] instream_size_b The size of the stream instream_b in bytes. * \param [out] outstream_output Stream "output". * \param [in] outstream_size_output The size of the stream outstream_output in bytes. */ void StreamFMA( uint64_t ticks_StreamFMAKernel, const void *instream_a, size_t instream_size_a, const void *instream_b, size_t instream_size_b, void *outstream_output, size_t outstream_size_output); /** * \brief Basic static non-blocking function for the interface 'default'. * * Schedule to run on an engine and return immediately. * The status of the run can be checked either by ::max_wait or ::max_nowait; * note that one of these *must* be called, so that associated memory can be released. * * * \param [in] ticks_StreamFMAKernel The number of ticks for which kernel "StreamFMAKernel" will run. * \param [in] instream_a Stream "a". * \param [in] instream_size_a The size of the stream instream_a in bytes. * \param [in] instream_b Stream "b". * \param [in] instream_size_b The size of the stream instream_b in bytes. * \param [out] outstream_output Stream "output". * \param [in] outstream_size_output The size of the stream outstream_output in bytes. * \return A handle on the execution status, or NULL in case of error. */ max_run_t *StreamFMA_nonblock( uint64_t ticks_StreamFMAKernel, const void *instream_a, size_t instream_size_a, const void *instream_b, size_t instream_size_b, void *outstream_output, size_t outstream_size_output); /** * \brief Advanced static interface, structure for the engine interface 'default' * */ typedef struct { uint64_t ticks_StreamFMAKernel; /**< [in] The number of ticks for which kernel "StreamFMAKernel" will run. */ const void *instream_a; /**< [in] Stream "a". */ size_t instream_size_a; /**< [in] The size of the stream instream_a in bytes. */ const void *instream_b; /**< [in] Stream "b". */ size_t instream_size_b; /**< [in] The size of the stream instream_b in bytes. */ void *outstream_output; /**< [out] Stream "output". */ size_t outstream_size_output; /**< [in] The size of the stream outstream_output in bytes. */ } StreamFMA_actions_t; /** * \brief Advanced static function for the interface 'default'. * * \param [in] engine The engine on which the actions will be executed. * \param [in,out] interface_actions Actions to be executed. */ void StreamFMA_run( max_engine_t *engine, StreamFMA_actions_t *interface_actions); /** * \brief Advanced static non-blocking function for the interface 'default'. * * Schedule the actions to run on the engine and return immediately. * The status of the run can be checked either by ::max_wait or ::max_nowait; * note that one of these *must* be called, so that associated memory can be released. * * * \param [in] engine The engine on which the actions will be executed. * \param [in] interface_actions Actions to be executed. * \return A handle on the execution status of the actions, or NULL in case of error. */ max_run_t *StreamFMA_run_nonblock( max_engine_t *engine, StreamFMA_actions_t *interface_actions); /** * \brief Group run advanced static function for the interface 'default'. * * \param [in] group Group to use. * \param [in,out] interface_actions Actions to run. * * Run the actions on the first device available in the group. */ void StreamFMA_run_group(max_group_t *group, StreamFMA_actions_t *interface_actions); /** * \brief Group run advanced static non-blocking function for the interface 'default'. * * * Schedule the actions to run on the first device available in the group and return immediately. * The status of the run must be checked with ::max_wait. * Note that use of ::max_nowait is prohibited with non-blocking running on groups: * see the ::max_run_group_nonblock documentation for more explanation. * * \param [in] group Group to use. * \param [in] interface_actions Actions to run. * \return A handle on the execution status of the actions, or NULL in case of error. */ max_run_t *StreamFMA_run_group_nonblock(max_group_t *group, StreamFMA_actions_t *interface_actions); /** * \brief Array run advanced static function for the interface 'default'. * * \param [in] engarray The array of devices to use. * \param [in,out] interface_actions The array of actions to run. * * Run the array of actions on the array of engines. The length of interface_actions * must match the size of engarray. */ void StreamFMA_run_array(max_engarray_t *engarray, StreamFMA_actions_t *interface_actions[]); /** * \brief Array run advanced static non-blocking function for the interface 'default'. * * * Schedule to run the array of actions on the array of engines, and return immediately. * The length of interface_actions must match the size of engarray. * The status of the run can be checked either by ::max_wait or ::max_nowait; * note that one of these *must* be called, so that associated memory can be released. * * \param [in] engarray The array of devices to use. * \param [in] interface_actions The array of actions to run. * \return A handle on the execution status of the actions, or NULL in case of error. */ max_run_t *StreamFMA_run_array_nonblock(max_engarray_t *engarray, StreamFMA_actions_t *interface_actions[]); /** * \brief Converts a static-interface action struct into a dynamic-interface max_actions_t struct. * * Note that this is an internal utility function used by other functions in the static interface. * * \param [in] maxfile The maxfile to use. * \param [in] interface_actions The interface-specific actions to run. * \return The dynamic-interface actions to run, or NULL in case of error. */ max_actions_t* StreamFMA_convert(max_file_t *maxfile, StreamFMA_actions_t *interface_actions); /** * \brief Initialise a maxfile. */ max_file_t* StreamFMA_init(void); /* Error handling functions */ int StreamFMA_has_errors(void); const char* StreamFMA_get_errors(void); void StreamFMA_clear_errors(void); /* Free statically allocated maxfile data */ void StreamFMA_free(void); /* returns: -1 = error running command; 0 = no error reported */ int StreamFMA_simulator_start(void); /* returns: -1 = error running command; 0 = no error reported */ int StreamFMA_simulator_stop(void); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* SLIC_DECLARATIONS_StreamFMA_H */ #endif /* SLIC_NO_DECLARATIONS */ #ifdef PHOTON_NODE_DATA #define PHOTON_NODE_DATA_PRESENT 1 PHOTON_NODE_DATA(StreamFMAKernel, 8, NodeInputMappedReg, "Scalar input (io_output_force_disabled)", "com.maxeler.maxcompiler.v2.kernelcompiler.stdlib.core.IO.output(IO.java:836)\nperfmodels.StreamFMAKernel.(StreamFMAKernel.maxj:21)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 9, NodeNot, "~", "com.maxeler.maxcompiler.v2.kernelcompiler.stdlib.core.IO.output(IO.java:836)\nperfmodels.StreamFMAKernel.(StreamFMAKernel.maxj:21)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 0, NodeInputMappedReg, "Scalar input (io_a_force_disabled)", "com.maxeler.maxcompiler.v2.kernelcompiler.stdlib.core.IO.input(IO.java:630)\nperfmodels.StreamFMAKernel.(StreamFMAKernel.maxj:15)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 1, NodeNot, "~", "com.maxeler.maxcompiler.v2.kernelcompiler.stdlib.core.IO.input(IO.java:630)\nperfmodels.StreamFMAKernel.(StreamFMAKernel.maxj:15)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 2, NodeInput, "Input(a)", "com.maxeler.maxcompiler.v2.kernelcompiler.stdlib.core.IO.input(IO.java:630)\nperfmodels.StreamFMAKernel.(StreamFMAKernel.maxj:15)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 3, NodeInputMappedReg, "Scalar input (io_b_force_disabled)", "com.maxeler.maxcompiler.v2.kernelcompiler.stdlib.core.IO.input(IO.java:630)\nperfmodels.StreamFMAKernel.(StreamFMAKernel.maxj:16)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 4, NodeNot, "~", "com.maxeler.maxcompiler.v2.kernelcompiler.stdlib.core.IO.input(IO.java:630)\nperfmodels.StreamFMAKernel.(StreamFMAKernel.maxj:16)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 5, NodeInput, "Input(b)", "com.maxeler.maxcompiler.v2.kernelcompiler.stdlib.core.IO.input(IO.java:630)\nperfmodels.StreamFMAKernel.(StreamFMAKernel.maxj:16)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 6, NodeAdd, "+", "com.maxeler.maxcompiler.v2.kernelcompiler.types.base.DFEVar.add(DFEVar.java:1010)\nperfmodels.StreamFMAKernel.(StreamFMAKernel.maxj:19)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 11, NodeOutput, "Output(output)", "com.maxeler.maxcompiler.v2.kernelcompiler.stdlib.core.IO.output(IO.java:836)\nperfmodels.StreamFMAKernel.(StreamFMAKernel.maxj:21)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 16, NodeConstantRawBits, "{HWOffsetFix:1, 0, UNSIGNED}\n0x1; 1.0", "com.maxeler.platform.max5.manager.Max5ManagerBase.addKernel(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 26, NodeConstantRawBits, "{HWOffsetFix:1, 0, UNSIGNED}\n0x1; 1.0", "com.maxeler.platform.max5.manager.Max5ManagerBase.addKernel(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 13, NodeConstantRawBits, "{HWOffsetFix:49, 0, UNSIGNED}\n0x1000000000000; 2.81474976710656E14", "com.maxeler.platform.max5.manager.Max5ManagerBase.addKernel(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 14, NodeCounter, "Counter(NUMERIC_INCREMENTING)\nInc: 1\nReset: 0\nInit: 0", "com.maxeler.platform.max5.manager.Max5ManagerBase.addKernel(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 15, NodeStreamOffset, "stream offset: 1", "com.maxeler.platform.max5.manager.Max5ManagerBase.addKernel(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 17, NodeOutputMappedReg, "Scalar output (current_run_cycle_count)", "com.maxeler.platform.max5.manager.Max5ManagerBase.addKernel(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 25, NodeConstantRawBits, "{HWOffsetFix:1, 0, UNSIGNED}\n0x1; 1.0", "com.maxeler.platform.max5.manager.Max5ManagerBase.addKernel(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 19, NodeConstantRawBits, "{HWOffsetFix:49, 0, UNSIGNED}\n0x1000000000000; 2.81474976710656E14", "com.maxeler.platform.max5.manager.Max5ManagerBase.addKernel(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 20, NodeCounter, "Counter(NUMERIC_INCREMENTING)\nInc: 1\nReset: 0\nInit: 0", "com.maxeler.platform.max5.manager.Max5ManagerBase.addKernel(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 22, NodeInputMappedReg, "Scalar input (run_cycle_count)", "com.maxeler.platform.max5.manager.Max5ManagerBase.addKernel(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 24, NodeEqInlined, "==", "com.maxeler.platform.max5.manager.Max5ManagerBase.addKernel(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") PHOTON_NODE_DATA(StreamFMAKernel, 21, NodeFlush, "flush on trigger", "com.maxeler.platform.max5.manager.Max5ManagerBase.addKernel(Unknown Source)\nperfmodels.StreamFMAManager.(StreamFMAManager.maxj:13)\nperfmodels.StreamFMAManager.main(StreamFMAManager.maxj:20)\n") #endif #ifdef SLIC_USE_DEFINITIONS #include #include #include #include #include #include static max_file_t *stored_maxfile = NULL; static max_engine_t *stored_engine = NULL; static char *stored_error = NULL; static int stored_has_error = 0; static pthread_once_t slic_bs_is_initialised = PTHREAD_ONCE_INIT; static void set_error(const char *error_str) { stored_has_error = 1; if(stored_error == NULL) { stored_error = strdup(error_str); } else { char *nerr = malloc(strlen(stored_error) + strlen(error_str) + 2); sprintf(nerr, "%s\n%s", stored_error, error_str); free(stored_error); stored_error = nerr; } } static void set_error_and_free(char *error_str){ set_error(error_str); free(error_str); } int StreamFMA_has_errors(void) { return stored_has_error; } const char* StreamFMA_get_errors(void) { return stored_error; } void StreamFMA_clear_errors(void) { free(stored_error); stored_error = NULL; stored_has_error = 0; } static char StreamFMA_use_simulation[16]; static void StreamFMA_def_use_simulation(void) { long pid = ((long) getpid()) % 100000; snprintf(StreamFMA_use_simulation, 16, "StreamFM_%05ld_", pid); } static const char *StreamFMA_check_use_simulation(void) { StreamFMA_def_use_simulation(); const char *use_sim = max_config_get_string(MAX_CONFIG_USE_SIMULATION); if (use_sim == NULL) { use_sim = StreamFMA_use_simulation; max_config_set_string(MAX_CONFIG_USE_SIMULATION, use_sim); } return use_sim; } static int StreamFMA_simulation_launch = 0; int StreamFMA_simulator_start(void) { int retval = 0; const char *use_sim = StreamFMA_check_use_simulation(); char buff[1024]; snprintf(buff, 1024, "PATH=simutils:$PATH maxcompilersim -d 1 -n %s -c MAX5C -S simutils restart", use_sim); FILE *pipe_fp = popen(buff, "r"); if (pipe_fp == NULL) { strncat(buff, " : failed to execute.", (1024 - strlen(buff))); set_error(buff); return -1; } while (fgets(buff, 1024, pipe_fp) != NULL) { /* Uncomment this to get simulator command output */ /* fprintf(stderr, buff); */ if (strstr(buff, "Error")) { set_error(buff); retval = -1; } } pclose(pipe_fp); return retval; } int StreamFMA_simulator_stop(void) { const char *use_sim = StreamFMA_check_use_simulation(); char buff[1024]; snprintf(buff, 1024, "PATH=simutils:$PATH maxcompilersim -d 1 -n %s -c MAX5C -S simutils stop", use_sim); FILE *pipe_fp = popen(buff, "r"); if (pipe_fp == NULL) { strncat(buff, " : failed to execute.", (1024 - strlen(buff))); set_error(buff); return -1; } while (fgets(buff, 1024, pipe_fp) != NULL) { /* Uncomment this to get simulator command output */ /* fprintf(stderr, buff); */ ; } pclose(pipe_fp); return 0; } static void StreamFMA_static_init(void) { stored_maxfile = StreamFMA_init(); if (stored_maxfile == NULL || !max_ok(stored_maxfile->errors)) { stored_maxfile = NULL; if(max_config_get_bool(MAX_CONFIG_STATIC_INTERFACE_ABORT_ON_ERROR)) abort(); else { set_error("Unable to load maxfile"); return; } } if(!max_ok(max_global_errors())) { set_error_and_free(max_errors_trace(max_global_errors())); return; } if(!max_config_get_bool(MAX_CONFIG_STATIC_INTERFACE_ABORT_ON_ERROR)) max_errors_mode(stored_maxfile->errors, 0); time_t timeout_previous = max_load_timeout(stored_maxfile, 30); const char *use_sim = StreamFMA_check_use_simulation(); if (max_ping_daemon(stored_maxfile, use_sim) == 0) { int sim_stat = StreamFMA_simulator_start(); if ((sim_stat == 0) && (max_ping_daemon(stored_maxfile, use_sim) == 1)) { StreamFMA_simulation_launch = 1; } else { set_error("Error: An error occurred while trying to start the simulation infrastructure automatically."); set_error("Error: Check that 'use_simulation=' is set correctly in your SLiC configuration"); set_error("Error: and that the associated simulated system daemon is running."); max_file_free(stored_maxfile); stored_maxfile = NULL; return; } } stored_engine = max_load(stored_maxfile, "*"); if (!max_ok(stored_maxfile->errors)) { if(max_config_get_bool(MAX_CONFIG_STATIC_INTERFACE_ABORT_ON_ERROR)) { fprintf(stderr, "\nUnable to load engine: aborting now.\n\n"); fflush(stderr); abort(); } else { set_error_and_free(max_errors_trace(stored_maxfile->errors)); max_file_free(stored_maxfile); stored_maxfile = NULL; return; } } max_load_timeout(stored_maxfile, timeout_previous); } void StreamFMA_free(void) { if (stored_engine != NULL) { max_unload(stored_engine); stored_engine = NULL; } if (stored_maxfile != NULL) { max_file_free(stored_maxfile); stored_maxfile = NULL; } if (stored_error != NULL) { free(stored_error); stored_error = NULL; } if (StreamFMA_simulation_launch == 1) { int sim_stat = StreamFMA_simulator_stop(); if (sim_stat != 0 ) { fprintf(stderr, "Error stopping simulator."); } StreamFMA_simulation_launch = 0; } } static int StreamFMA_get_pcie_alignment(void) { #ifdef StreamFMA_PCIE_ALIGNMENT return ((StreamFMA_PCIE_ALIGNMENT < 1) ? 16 : StreamFMA_PCIE_ALIGNMENT); #else return 16; #endif } static int StreamFMA_check_aligned(const void *data) { uintptr_t pointer = (uintptr_t) data; int alignment = StreamFMA_get_pcie_alignment(); return (pointer % alignment) ? 1 : 0; } static void *StreamFMA_malloc_aligned(const size_t size) { void *ptr; int alignment = StreamFMA_get_pcie_alignment(); posix_memalign(&ptr, alignment, size); return ptr; } /*----------------------------------------------------------------------------*/ /*---------------------------- Interface default -----------------------------*/ /*----------------------------------------------------------------------------*/ #define CHECK_ERRORS_ST(ST, RET) if(!max_ok(ST->errors)) { if(max_config_get_bool(MAX_CONFIG_STATIC_INTERFACE_ABORT_ON_ERROR)) { fprintf(stderr, "%s\n", max_errors_trace(ST->errors)); abort(); } set_error_and_free(max_errors_trace(ST->errors)); return RET; } #define CHECK_NULL(VALUE, MESSAGE, RET) if(VALUE == NULL) { if (max_config_get_bool(MAX_CONFIG_STATIC_INTERFACE_ABORT_ON_ERROR)) { fprintf(stderr, "%s\n%s\n", (stored_error == NULL) ? "" : stored_error, MESSAGE); abort(); } set_error(MESSAGE); return RET; } typedef struct StreamFMA_callback_stream { uint8_t *user_ptr; uint8_t *aligned_ptr; size_t size; int is_output; } StreamFMA_callback_stream_t; typedef struct StreamFMA_callback_data { StreamFMA_callback_stream_t stream[3]; int count; int max_count; } StreamFMA_callback_data_t; static void StreamFMA_callback_internal(void *cb_data) { StreamFMA_callback_data_t *data = (StreamFMA_callback_data_t*) cb_data; for (int i = 0 ; i < data->count ; i++ ) { StreamFMA_callback_stream_t *s = &data->stream[i]; if (s->is_output && (s->size > 0)) { memcpy(s->user_ptr, s->aligned_ptr, s->size); } free(s->aligned_ptr); } free(data); } static max_actions_t* StreamFMA_convert_internal( max_file_t *maxfile, StreamFMA_actions_t *interface_actions, int is_internal_call, void (**callback_func)(void*), void **callback_data) { max_actions_t *actions = max_actions_init(maxfile, NULL); if(actions == NULL) return NULL; #define CHECK_ERRORS if(!max_ok(actions->errors)) { set_error_and_free(max_errors_trace(actions->errors)); return NULL; } StreamFMA_callback_data_t *cb_data = NULL; int use_callback = (callback_func != NULL) && (callback_data != NULL); if (use_callback) { cb_data = malloc(sizeof(StreamFMA_callback_data_t)); if (cb_data == NULL) { fprintf(stderr, "Unable to allocate memory for stream callback data in function StreamFMA_convert_internal\n"); return NULL; } cb_data->max_count = 3; cb_data->count = 0; *callback_data = cb_data; *callback_func = &StreamFMA_callback_internal; } /* code for scalar StreamFMAKernel.run_cycle_count */ uint64_t ticks_StreamFMAKernel = interface_actions->ticks_StreamFMAKernel; max_set_ticks(actions, "StreamFMAKernel", ticks_StreamFMAKernel); CHECK_ERRORS; /* end of code for scalar StreamFMAKernel.run_cycle_count*/ /* code for stream a */ size_t instream_size_a = interface_actions->instream_size_a; if (instream_size_a > 0) { const void *stream_ptr = interface_actions->instream_a; if (use_callback && (1 == StreamFMA_check_aligned(interface_actions->instream_a))) { void *aligned_instream_a = malloc(instream_size_a); if (aligned_instream_a == NULL) { max_report_error_slic(actions->errors, __FILE__, __LINE__, 526, "Failed to allocate aligned memory for stream 'a'"); CHECK_ERRORS; } (&cb_data->stream[cb_data->count])->user_ptr = (uint8_t*) interface_actions->instream_a; (&cb_data->stream[cb_data->count])->aligned_ptr = (uint8_t*) aligned_instream_a; (&cb_data->stream[cb_data->count])->size = instream_size_a; (&cb_data->stream[cb_data->count])->is_output = 0; cb_data->count += 1; memcpy(aligned_instream_a, interface_actions->instream_a, instream_size_a); stream_ptr = aligned_instream_a; } max_queue_input(actions, "a", stream_ptr, instream_size_a); CHECK_ERRORS; } /* end of code for stream a */ /* code for stream b */ size_t instream_size_b = interface_actions->instream_size_b; if (instream_size_b > 0) { const void *stream_ptr = interface_actions->instream_b; if (use_callback && (1 == StreamFMA_check_aligned(interface_actions->instream_b))) { void *aligned_instream_b = malloc(instream_size_b); if (aligned_instream_b == NULL) { max_report_error_slic(actions->errors, __FILE__, __LINE__, 526, "Failed to allocate aligned memory for stream 'b'"); CHECK_ERRORS; } (&cb_data->stream[cb_data->count])->user_ptr = (uint8_t*) interface_actions->instream_b; (&cb_data->stream[cb_data->count])->aligned_ptr = (uint8_t*) aligned_instream_b; (&cb_data->stream[cb_data->count])->size = instream_size_b; (&cb_data->stream[cb_data->count])->is_output = 0; cb_data->count += 1; memcpy(aligned_instream_b, interface_actions->instream_b, instream_size_b); stream_ptr = aligned_instream_b; } max_queue_input(actions, "b", stream_ptr, instream_size_b); CHECK_ERRORS; } /* end of code for stream b */ /* code for stream output */ size_t outstream_size_output = interface_actions->outstream_size_output; if (outstream_size_output > 0) { void *stream_ptr = interface_actions->outstream_output; if (use_callback && (1 == StreamFMA_check_aligned(interface_actions->outstream_output))) { void *aligned_outstream_output = malloc(outstream_size_output); if (aligned_outstream_output == NULL) { max_report_error_slic(actions->errors, __FILE__, __LINE__, 526, "Failed to allocate aligned memory for stream 'output'"); CHECK_ERRORS; } (&cb_data->stream[cb_data->count])->user_ptr = (uint8_t*) interface_actions->outstream_output; (&cb_data->stream[cb_data->count])->aligned_ptr = (uint8_t*) aligned_outstream_output; (&cb_data->stream[cb_data->count])->size = outstream_size_output; (&cb_data->stream[cb_data->count])->is_output = 1; cb_data->count += 1; stream_ptr = aligned_outstream_output; } max_queue_output(actions, "output", stream_ptr, outstream_size_output); CHECK_ERRORS; } /* end of code for stream output */ if (use_callback && cb_data->count == 0) { *callback_data = NULL; *callback_func = NULL; free(cb_data); } return actions; #undef CHECK_ERRORS } void StreamFMA( uint64_t ticks_StreamFMAKernel, const void *instream_a, size_t instream_size_a, const void *instream_b, size_t instream_size_b, void *outstream_output, size_t outstream_size_output) { (void) pthread_once(&slic_bs_is_initialised, StreamFMA_static_init); CHECK_NULL(stored_maxfile, "Maxfile was not loaded", ); max_run_t *run = StreamFMA_nonblock(ticks_StreamFMAKernel, instream_a, instream_size_a, instream_b, instream_size_b, outstream_output, outstream_size_output); CHECK_NULL(run, "Unable to run actions", ); max_wait(run); } max_run_t *StreamFMA_nonblock( uint64_t ticks_StreamFMAKernel, const void *instream_a, size_t instream_size_a, const void *instream_b, size_t instream_size_b, void *outstream_output, size_t outstream_size_output) { StreamFMA_actions_t interface_actions; interface_actions.ticks_StreamFMAKernel = ticks_StreamFMAKernel; interface_actions.instream_a = instream_a; interface_actions.instream_size_a = instream_size_a; interface_actions.instream_b = instream_b; interface_actions.instream_size_b = instream_size_b; interface_actions.outstream_output = outstream_output; interface_actions.outstream_size_output = outstream_size_output; (void) pthread_once(&slic_bs_is_initialised, StreamFMA_static_init); CHECK_NULL(stored_maxfile, "Maxfile was not loaded", NULL); void (*cb_func)(void*) = NULL; void *cb_data = NULL; max_actions_t *actions = StreamFMA_convert_internal(stored_maxfile, &interface_actions, 1, &cb_func, &cb_data); CHECK_NULL(actions, "Unable to build actions", NULL); max_validate(actions); CHECK_ERRORS_ST(actions, NULL); CHECK_ERRORS_ST(stored_engine, NULL); max_run_t *run; if (cb_func == NULL) { run = max_run_nonblock(stored_engine, actions); } else { run = max_run_nonblock_with_cb(stored_engine, actions, cb_func, cb_data); } CHECK_NULL(run, "Unable to run actions", NULL); CHECK_ERRORS_ST(actions, NULL); max_actions_free(actions); return run; } void StreamFMA_run( max_engine_t *engine, StreamFMA_actions_t *interface_actions) { max_run_t *run = StreamFMA_run_nonblock(engine, interface_actions); CHECK_NULL(run, "Unable to run actions", ); max_wait(run); } max_run_t *StreamFMA_run_nonblock( max_engine_t *engine, StreamFMA_actions_t *interface_actions) { max_file_t *maxfile = max_engine_get_max_file(engine); void (*cb_func)(void*) = NULL; void *cb_data = NULL; max_actions_t *actions = StreamFMA_convert_internal(maxfile, interface_actions, 1, &cb_func, &cb_data); CHECK_NULL(actions, "Unable to build actions", NULL); max_validate(actions); CHECK_ERRORS_ST(actions, NULL); max_run_t *run; if (cb_func == NULL) { run = max_run_nonblock(engine, actions); } else { run = max_run_nonblock_with_cb(engine, actions, cb_func, cb_data); } CHECK_NULL(run, "Unable to run actions", NULL); max_actions_free(actions); return run; } /** * \brief Group run advanced static function for the interface 'default'. * * \param [in] group Group to use. * \param [in,out] interface_actions Actions to run. * * Run the actions on the first device available in the group. */ void StreamFMA_run_group(max_group_t *group, StreamFMA_actions_t *interface_actions) { max_run_t *run = StreamFMA_run_group_nonblock(group, interface_actions); CHECK_NULL(run, "Unable to run actions", ); max_wait(run); } /** * \brief Group run advanced static non-blocking function for the interface 'default'. * * * Schedule the actions to run on the first device available in the group and return immediately. * The status of the run must be checked with ::max_wait. * Note that use of ::max_nowait is prohibited with non-blocking running on groups: * see the ::max_run_group_nonblock documentation for more explanation. * * \param [in] group Group to use. * \param [in] interface_actions Actions to run. * \return A handle on the execution status of the actions, or NULL in case of error. */ max_run_t *StreamFMA_run_group_nonblock(max_group_t *group, StreamFMA_actions_t *interface_actions) { max_file_t *maxfile = max_group_get_max_file(group); max_actions_t *actions = StreamFMA_convert_internal(maxfile, interface_actions, 1, NULL, NULL); if(actions == NULL) return NULL; if(!max_ok(actions->errors)) return NULL; max_validate(actions); max_run_t *run = max_run_group_nonblock(group, actions); max_actions_free(actions); return run; } /** * \brief Array run advanced static function for the interface 'default'. * * \param [in] engarray The array of devices to use. * \param [in,out] interface_actions The array of actions to run. * * Run the array of actions on the array of engines. The length of interface_actions * must match the size of engarray. */ void StreamFMA_run_array(max_engarray_t *engarray, StreamFMA_actions_t *interface_actions[]) { max_run_t *run = StreamFMA_run_array_nonblock(engarray, interface_actions); CHECK_NULL(run, "Unable to run actions", ); max_wait(run); } /** * \brief Array run advanced static non-blocking function for the interface 'default'. * * * Schedule to run the array of actions on the array of engines, and return immediately. * The length of interface_actions must match the size of engarray. * The status of the run can be checked either by ::max_wait or ::max_nowait; * note that one of these *must* be called, so that associated memory can be released. * * \param [in] engarray The array of devices to use. * \param [in] interface_actions The array of actions to run. * \return A handle on the execution status of the actions, or NULL in case of error. */ max_run_t *StreamFMA_run_array_nonblock(max_engarray_t *engarray, StreamFMA_actions_t *interface_actions[]) { max_file_t *maxfile = max_engarray_get_max_file(engarray, 0); int i; max_actarray_t *actarray = max_actarray_init(maxfile, engarray->size); if (actarray == NULL) return NULL; max_actions_t **arr_actions = malloc(engarray->size * sizeof(max_actions_t*)); for ( i = 0 ; i < actarray->size; i++ ) { max_actions_t *actions = StreamFMA_convert_internal(maxfile, interface_actions[i], 1, NULL, NULL); if (actions == NULL) return NULL; arr_actions[i] = actions; max_set_action(actarray, i, actions); } max_run_t *run = max_run_array_nonblock(engarray, actarray); for ( i = 0 ; i < actarray->size ; i++ ) { max_actions_free(arr_actions[i]); } max_actarray_free(actarray); free(arr_actions); return run; } /** * \brief Converts a static-interface action struct into a dynamic-interface max_actions_t struct. * * Note that this is an internal utility function used by other functions in the static interface. * * \param [in] maxfile The maxfile to use. * \param [in] interface_actions The interface-specific actions to run. * \return The dynamic-interface actions to run, or NULL in case of error. */ max_actions_t* StreamFMA_convert(max_file_t *maxfile, StreamFMA_actions_t *interface_actions) { return StreamFMA_convert_internal(maxfile, interface_actions, 0, NULL, NULL); } #undef CHECK_ERRORS_ST #undef CHECK_NULL #endif /* SLIC_USE_DEFINITIONS */ #ifdef SLIC_DYNAMIC_CODE SLIC_MODE_START(default) SLIC_MODE_END(default) #endif /* SLIC_DYNAMIC_CODE */ #ifdef SKIN_META_DATA PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PG1h eGZpbGUgZm9ybWF0LXZlcnNpb249IjIwMTIwMjAwIiBoZWFkZXI9IlN0cmVhbUZNQS5oIiBuYW1l PSJTdHJlYW1GTUEiPjxjb25zdGFudCBuYW1lPSJEWU5BTUlDX0NMT0NLU19FTkFCTEVEIiB0eXBl PSJsb25nIiB2YWx1ZT0iMCIvPjxjb25zdGFudCBuYW1lPSJQQ0lFX0FMSUdOTUVOVCIgdHlwZT0i bG9uZyIgdmFsdWU9IjE2Ii8+PGVuZ2luZW1vZGUgbmFtZT0iZGVmYXVsdCI+PGZ1bmN0aW9uIG5h bWU9IlN0cmVhbUZNQSIgcmV0dXJuLXZhbHVlPSJ2b2lkIj48c2NhbGFyIGRlc2M9IlRoZSBudW1i ZXIgb2YgdGlja3MgZm9yIHdoaWNoIGtlcm5lbCAmcXVvdDtTdHJlYW1GTUFLZXJuZWwmcXVvdDsg d2lsbCBydW4uIiBkaXJlY3Rpb249IklucHV0IiBuYW1lPSJ0aWNrc19TdHJlYW1GTUFLZXJuZWwi IHR5cGU9InVpbnQ2NF90Ii8+PGFycmF5IGRlc2M9IlN0cmVhbSAmcXVvdDthJnF1b3Q7LiIgZGly ZWN0aW9uPSJJbnB1dCIgbmFtZT0iaW5zdHJlYW1fYSIgc2l6ZT0iaW5zdHJlYW1fc2l6ZV9hIiB0 cmFuc3Bvc2U9ImZhbHNlIiB0eXBlPSJ2b2lkIi8+PHNjYWxhciBkZXNjPSJUaGUgc2l6ZSBvZiB0 aGUgc3RyZWFtIGluc3RyZWFtX2EgaW4gYnl0ZXMuIiBkaXJlY3Rpb249IklucHV0IiBuYW1lPSJp bnN0cmVhbV9zaXplX2EiIHR5cGU9InVpbnQ2NF90Ii8+PGFycmF5IGRlc2M9IlN0cmVhbSAmcXVv dDtiJnF1b3Q7LiIgZGlyZWN0aW9uPSJJbnB1dCIgbmFtZT0iaW5zdHJlYW1fYiIgc2l6ZT0iaW5z dHJlYW1fc2l6ZV9iIiB0cmFuc3Bvc2U9ImZhbHNlIiB0eXBlPSJ2b2lkIi8+PHNjYWxhciBkZXNj PSJUaGUgc2l6ZSBvZiB0aGUgc3RyZWFtIGluc3RyZWFtX2IgaW4gYnl0ZXMuIiBkaXJlY3Rpb249 IklucHV0IiBuYW1lPSJpbnN0cmVhbV9zaXplX2IiIHR5cGU9InVpbnQ2NF90Ii8+PGFycmF5IGRl c2M9IlN0cmVhbSAmcXVvdDtvdXRwdXQmcXVvdDsuIiBkaXJlY3Rpb249Ik91dHB1dCIgbmFtZT0i b3V0c3RyZWFtX291dHB1dCIgc2l6ZT0ib3V0c3RyZWFtX3NpemVfb3V0cHV0IiB0cmFuc3Bvc2U9 ImZhbHNlIiB0eXBlPSJ2b2lkIi8+PHNjYWxhciBkZXNjPSJUaGUgc2l6ZSBvZiB0aGUgc3RyZWFt IG91dHN0cmVhbV9vdXRwdXQgaW4gYnl0ZXMuIiBkaXJlY3Rpb249IklucHV0IiBuYW1lPSJvdXRz dHJlYW1fc2l6ZV9vdXRwdXQiIHR5cGU9InVpbnQ2NF90Ii8+PC9mdW5jdGlvbj48L2VuZ2luZW1v ZGU+PC9tYXhmaWxlPg== #endif /* SKIN_META_DATA */ #ifdef SLIC_B64_DEFINITIONS I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxtYXRoLmg+CiNpbmNsdWRlIDxwdGhyZWFkLmg+ CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3RkbGli Lmg+CnN0YXRpYyBtYXhfZmlsZV90ICpzdG9yZWRfbWF4ZmlsZSA9IE5VTEw7CnN0YXRpYyBtYXhf ZW5naW5lX3QgKnN0b3JlZF9lbmdpbmUgPSBOVUxMOwpzdGF0aWMgY2hhciAqc3RvcmVkX2Vycm9y ID0gTlVMTDsKc3RhdGljIGludCBzdG9yZWRfaGFzX2Vycm9yID0gMDsKc3RhdGljIHB0aHJlYWRf b25jZV90IHNsaWNfYnNfaXNfaW5pdGlhbGlzZWQgPSBQVEhSRUFEX09OQ0VfSU5JVDsKCnN0YXRp YyB2b2lkIHNldF9lcnJvcihjb25zdCBjaGFyICplcnJvcl9zdHIpCnsKCXN0b3JlZF9oYXNfZXJy b3IgPSAxOyAKCWlmKHN0b3JlZF9lcnJvciA9PSBOVUxMKSB7CgkJc3RvcmVkX2Vycm9yID0gc3Ry ZHVwKGVycm9yX3N0cik7Cgl9IGVsc2UgewoJCWNoYXIgKm5lcnIgPSBtYWxsb2Moc3RybGVuKHN0 b3JlZF9lcnJvcikgKyBzdHJsZW4oZXJyb3Jfc3RyKSArIDIpOwoJCXNwcmludGYobmVyciwgIiVz XG4lcyIsIHN0b3JlZF9lcnJvciwgZXJyb3Jfc3RyKTsKCQlmcmVlKHN0b3JlZF9lcnJvcik7CgkJ c3RvcmVkX2Vycm9yID0gbmVycjsKCX0KfQpzdGF0aWMgdm9pZCBzZXRfZXJyb3JfYW5kX2ZyZWUo Y2hhciAqZXJyb3Jfc3RyKXsKCXNldF9lcnJvcihlcnJvcl9zdHIpOwoJZnJlZShlcnJvcl9zdHIp Owp9CmludCBTdHJlYW1GTUFfaGFzX2Vycm9ycyh2b2lkKQp7CXJldHVybiBzdG9yZWRfaGFzX2Vy cm9yOyB9CmNvbnN0IGNoYXIqIFN0cmVhbUZNQV9nZXRfZXJyb3JzKHZvaWQpCnsJcmV0dXJuIHN0 b3JlZF9lcnJvcjsgfQp2b2lkIFN0cmVhbUZNQV9jbGVhcl9lcnJvcnModm9pZCkKewoJZnJlZShz dG9yZWRfZXJyb3IpOwoJc3RvcmVkX2Vycm9yID0gTlVMTDsKCXN0b3JlZF9oYXNfZXJyb3IgPSAw Owp9CgpzdGF0aWMgY2hhciBTdHJlYW1GTUFfdXNlX3NpbXVsYXRpb25bMTZdOwpzdGF0aWMgdm9p ZCBTdHJlYW1GTUFfZGVmX3VzZV9zaW11bGF0aW9uKHZvaWQpCnsKCWxvbmcgcGlkID0gKChsb25n KSBnZXRwaWQoKSkgJSAxMDAwMDA7CglzbnByaW50ZihTdHJlYW1GTUFfdXNlX3NpbXVsYXRpb24s IDE2LCAiU3RyZWFtRk1fJTA1bGRfIiwgcGlkKTsKfQpzdGF0aWMgY29uc3QgY2hhciAqU3RyZWFt Rk1BX2NoZWNrX3VzZV9zaW11bGF0aW9uKHZvaWQpCnsKCVN0cmVhbUZNQV9kZWZfdXNlX3NpbXVs YXRpb24oKTsKCWNvbnN0IGNoYXIgKnVzZV9zaW0gPSBtYXhfY29uZmlnX2dldF9zdHJpbmcoTUFY X0NPTkZJR19VU0VfU0lNVUxBVElPTik7CglpZiAodXNlX3NpbSA9PSBOVUxMKSB7CgkJdXNlX3Np bSA9IFN0cmVhbUZNQV91c2Vfc2ltdWxhdGlvbjsKCQltYXhfY29uZmlnX3NldF9zdHJpbmcoTUFY X0NPTkZJR19VU0VfU0lNVUxBVElPTiwgdXNlX3NpbSk7Cgl9CglyZXR1cm4gdXNlX3NpbTsKfQoK c3RhdGljIGludCBTdHJlYW1GTUFfc2ltdWxhdGlvbl9sYXVuY2ggPSAwOwppbnQgU3RyZWFtRk1B X3NpbXVsYXRvcl9zdGFydCh2b2lkKQp7CglpbnQgcmV0dmFsID0gMDsKCWNvbnN0IGNoYXIgKnVz ZV9zaW0gPSBTdHJlYW1GTUFfY2hlY2tfdXNlX3NpbXVsYXRpb24oKTsKCWNoYXIgYnVmZlsxMDI0 XTsKCXNucHJpbnRmKGJ1ZmYsIDEwMjQsICJQQVRIPXNpbXV0aWxzOiRQQVRIIG1heGNvbXBpbGVy c2ltIC1kIDEgLW4gJXMgLWMgTUFYNUMgLVMgc2ltdXRpbHMgcmVzdGFydCIsIHVzZV9zaW0pOwoJ RklMRSAqcGlwZV9mcCA9IHBvcGVuKGJ1ZmYsICJyIik7CglpZiAocGlwZV9mcCA9PSBOVUxMKSB7 CgkJc3RybmNhdChidWZmLCAiIDogZmFpbGVkIHRvIGV4ZWN1dGUuIiwgKDEwMjQgLSBzdHJsZW4o YnVmZikpKTsKCQlzZXRfZXJyb3IoYnVmZik7CgkJcmV0dXJuIC0xOwoJfQoJd2hpbGUgKGZnZXRz KGJ1ZmYsIDEwMjQsIHBpcGVfZnApICE9IE5VTEwpIHsKCQkvKiBVbmNvbW1lbnQgdGhpcyB0byBn ZXQgc2ltdWxhdG9yIGNvbW1hbmQgb3V0cHV0ICovCgkJLyogZnByaW50ZihzdGRlcnIsIGJ1ZmYp OyAqLwoJCWlmIChzdHJzdHIoYnVmZiwgIkVycm9yIikpIHsKCQkJc2V0X2Vycm9yKGJ1ZmYpOwoJ CQlyZXR2YWwgPSAtMTsKCQl9Cgl9CglwY2xvc2UocGlwZV9mcCk7CglyZXR1cm4gcmV0dmFsOwp9 CgppbnQgU3RyZWFtRk1BX3NpbXVsYXRvcl9zdG9wKHZvaWQpCnsKCWNvbnN0IGNoYXIgKnVzZV9z aW0gPSBTdHJlYW1GTUFfY2hlY2tfdXNlX3NpbXVsYXRpb24oKTsKCWNoYXIgYnVmZlsxMDI0XTsK CXNucHJpbnRmKGJ1ZmYsIDEwMjQsICJQQVRIPXNpbXV0aWxzOiRQQVRIIG1heGNvbXBpbGVyc2lt IC1kIDEgLW4gJXMgLWMgTUFYNUMgLVMgc2ltdXRpbHMgc3RvcCIsIHVzZV9zaW0pOwoJRklMRSAq cGlwZV9mcCA9IHBvcGVuKGJ1ZmYsICJyIik7CglpZiAocGlwZV9mcCA9PSBOVUxMKSB7CgkJc3Ry bmNhdChidWZmLCAiIDogZmFpbGVkIHRvIGV4ZWN1dGUuIiwgKDEwMjQgLSBzdHJsZW4oYnVmZikp KTsKCQlzZXRfZXJyb3IoYnVmZik7CgkJcmV0dXJuIC0xOwoJfQoJd2hpbGUgKGZnZXRzKGJ1ZmYs IDEwMjQsIHBpcGVfZnApICE9IE5VTEwpIHsKCQkvKiBVbmNvbW1lbnQgdGhpcyB0byBnZXQgc2lt dWxhdG9yIGNvbW1hbmQgb3V0cHV0ICovCgkJLyogZnByaW50ZihzdGRlcnIsIGJ1ZmYpOyAqLwoJ CTsKCX0KCXBjbG9zZShwaXBlX2ZwKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBTdHJlYW1G TUFfc3RhdGljX2luaXQodm9pZCkgCnsKCXN0b3JlZF9tYXhmaWxlID0gU3RyZWFtRk1BX2luaXQo KTsKCWlmIChzdG9yZWRfbWF4ZmlsZSA9PSBOVUxMIHx8ICFtYXhfb2soc3RvcmVkX21heGZpbGUt PmVycm9ycykpIHsKCQlzdG9yZWRfbWF4ZmlsZSA9IE5VTEw7CgkJaWYobWF4X2NvbmZpZ19nZXRf Ym9vbChNQVhfQ09ORklHX1NUQVRJQ19JTlRFUkZBQ0VfQUJPUlRfT05fRVJST1IpKSBhYm9ydCgp OwoJCWVsc2UgeyBzZXRfZXJyb3IoIlVuYWJsZSB0byBsb2FkIG1heGZpbGUiKTsgcmV0dXJuOyB9 Cgl9CglpZighbWF4X29rKG1heF9nbG9iYWxfZXJyb3JzKCkpKSB7CgkJc2V0X2Vycm9yX2FuZF9m cmVlKG1heF9lcnJvcnNfdHJhY2UobWF4X2dsb2JhbF9lcnJvcnMoKSkpOwoJCXJldHVybjsKCX0K CWlmKCFtYXhfY29uZmlnX2dldF9ib29sKE1BWF9DT05GSUdfU1RBVElDX0lOVEVSRkFDRV9BQk9S VF9PTl9FUlJPUikpCgkJbWF4X2Vycm9yc19tb2RlKHN0b3JlZF9tYXhmaWxlLT5lcnJvcnMsIDAp OwoJdGltZV90IHRpbWVvdXRfcHJldmlvdXMgPSBtYXhfbG9hZF90aW1lb3V0KHN0b3JlZF9tYXhm aWxlLCAzMCk7Cgljb25zdCBjaGFyICp1c2Vfc2ltID0gU3RyZWFtRk1BX2NoZWNrX3VzZV9zaW11 bGF0aW9uKCk7CglpZiAobWF4X3BpbmdfZGFlbW9uKHN0b3JlZF9tYXhmaWxlLCB1c2Vfc2ltKSA9 PSAwKSB7CgkJaW50IHNpbV9zdGF0ID0gU3RyZWFtRk1BX3NpbXVsYXRvcl9zdGFydCgpOwoJCWlm ICgoc2ltX3N0YXQgPT0gMCkgJiYgKG1heF9waW5nX2RhZW1vbihzdG9yZWRfbWF4ZmlsZSwgdXNl X3NpbSkgPT0gMSkpIHsKCQkJU3RyZWFtRk1BX3NpbXVsYXRpb25fbGF1bmNoID0gMTsKCQl9IGVs c2UgewoJCQlzZXRfZXJyb3IoIkVycm9yOiBBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSB0cnlpbmcg dG8gc3RhcnQgdGhlIHNpbXVsYXRpb24gaW5mcmFzdHJ1Y3R1cmUgYXV0b21hdGljYWxseS4iKTsK CQkJc2V0X2Vycm9yKCJFcnJvcjogQ2hlY2sgdGhhdCAndXNlX3NpbXVsYXRpb249PHNpbXVsYXRv cl9uYW1lPicgaXMgc2V0IGNvcnJlY3RseSBpbiB5b3VyIFNMaUMgY29uZmlndXJhdGlvbiIpOwoJ CQlzZXRfZXJyb3IoIkVycm9yOiBhbmQgdGhhdCB0aGUgYXNzb2NpYXRlZCBzaW11bGF0ZWQgc3lz dGVtIGRhZW1vbiBpcyBydW5uaW5nLiIpOwoJCQltYXhfZmlsZV9mcmVlKHN0b3JlZF9tYXhmaWxl KTsKCQkJc3RvcmVkX21heGZpbGUgPSBOVUxMOwoJCQlyZXR1cm47CgkJfQoJfQoJc3RvcmVkX2Vu Z2luZSA9IG1heF9sb2FkKHN0b3JlZF9tYXhmaWxlLCAiKiIpOwoJaWYgKCFtYXhfb2soc3RvcmVk X21heGZpbGUtPmVycm9ycykpIHsKCQlpZihtYXhfY29uZmlnX2dldF9ib29sKE1BWF9DT05GSUdf U1RBVElDX0lOVEVSRkFDRV9BQk9SVF9PTl9FUlJPUikpIHsKCQkJZnByaW50ZihzdGRlcnIsICJc blVuYWJsZSB0byBsb2FkIGVuZ2luZTogYWJvcnRpbmcgbm93LlxuXG4iKTsKCQkJZmZsdXNoKHN0 ZGVycik7CgkJCWFib3J0KCk7CgkJfSBlbHNlIHsKCQkJc2V0X2Vycm9yX2FuZF9mcmVlKG1heF9l cnJvcnNfdHJhY2Uoc3RvcmVkX21heGZpbGUtPmVycm9ycykpOwoJCQltYXhfZmlsZV9mcmVlKHN0 b3JlZF9tYXhmaWxlKTsKCQkJc3RvcmVkX21heGZpbGUgPSBOVUxMOwoJCQlyZXR1cm47CgkJfSAK CX0gCgltYXhfbG9hZF90aW1lb3V0KHN0b3JlZF9tYXhmaWxlLCB0aW1lb3V0X3ByZXZpb3VzKTsK fQp2b2lkIFN0cmVhbUZNQV9mcmVlKHZvaWQpCnsKCWlmIChzdG9yZWRfZW5naW5lICE9IE5VTEwp IHsKCQltYXhfdW5sb2FkKHN0b3JlZF9lbmdpbmUpOwoJCXN0b3JlZF9lbmdpbmUgPSBOVUxMOwoJ fQoJaWYgKHN0b3JlZF9tYXhmaWxlICE9IE5VTEwpIHsKCQltYXhfZmlsZV9mcmVlKHN0b3JlZF9t YXhmaWxlKTsKCQlzdG9yZWRfbWF4ZmlsZSA9IE5VTEw7Cgl9CglpZiAoc3RvcmVkX2Vycm9yICE9 IE5VTEwpIHsKCQlmcmVlKHN0b3JlZF9lcnJvcik7CgkJc3RvcmVkX2Vycm9yID0gTlVMTDsKCX0K CWlmIChTdHJlYW1GTUFfc2ltdWxhdGlvbl9sYXVuY2ggPT0gMSkgewoJCWludCBzaW1fc3RhdCA9 IFN0cmVhbUZNQV9zaW11bGF0b3Jfc3RvcCgpOwoJCWlmIChzaW1fc3RhdCAhPSAwICkgewoJCQlm cHJpbnRmKHN0ZGVyciwgIkVycm9yIHN0b3BwaW5nIHNpbXVsYXRvci4iKTsKCQl9CgkJU3RyZWFt Rk1BX3NpbXVsYXRpb25fbGF1bmNoID0gMDsKCX0KfQoKc3RhdGljIGludCBTdHJlYW1GTUFfZ2V0 X3BjaWVfYWxpZ25tZW50KHZvaWQpCnsKI2lmZGVmIFN0cmVhbUZNQV9QQ0lFX0FMSUdOTUVOVAoJ cmV0dXJuICgoU3RyZWFtRk1BX1BDSUVfQUxJR05NRU5UIDwgMSkgPyAxNiA6IFN0cmVhbUZNQV9Q Q0lFX0FMSUdOTUVOVCk7CiNlbHNlCglyZXR1cm4gMTY7CiNlbmRpZgp9CgpzdGF0aWMgaW50IFN0 cmVhbUZNQV9jaGVja19hbGlnbmVkKGNvbnN0IHZvaWQgKmRhdGEpCnsKCXVpbnRwdHJfdCBwb2lu dGVyID0gKHVpbnRwdHJfdCkgZGF0YTsKCWludCBhbGlnbm1lbnQgPSBTdHJlYW1GTUFfZ2V0X3Bj aWVfYWxpZ25tZW50KCk7CglyZXR1cm4gKHBvaW50ZXIgJSBhbGlnbm1lbnQpID8gMSA6IDA7Cn0K CnN0YXRpYyB2b2lkICpTdHJlYW1GTUFfbWFsbG9jX2FsaWduZWQoY29uc3Qgc2l6ZV90IHNpemUp CnsKCXZvaWQgKnB0cjsKCWludCBhbGlnbm1lbnQgPSBTdHJlYW1GTUFfZ2V0X3BjaWVfYWxpZ25t ZW50KCk7Cglwb3NpeF9tZW1hbGlnbigmcHRyLCBhbGlnbm1lbnQsIHNpemUpOwoJcmV0dXJuIHB0 cjsKfQoKCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0gSW50ZXJmYWNlIGRlZmF1bHQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwov Ki0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKCgojZGVmaW5lIENIRUNLX0VSUk9SU19TVChTVCwgUkVU KSBpZighbWF4X29rKFNULT5lcnJvcnMpKSB7IGlmKG1heF9jb25maWdfZ2V0X2Jvb2woTUFYX0NP TkZJR19TVEFUSUNfSU5URVJGQUNFX0FCT1JUX09OX0VSUk9SKSkgeyBmcHJpbnRmKHN0ZGVyciwg IiVzXG4iLCBtYXhfZXJyb3JzX3RyYWNlKFNULT5lcnJvcnMpKTsgYWJvcnQoKTsgfSBzZXRfZXJy b3JfYW5kX2ZyZWUobWF4X2Vycm9yc190cmFjZShTVC0+ZXJyb3JzKSk7IHJldHVybiBSRVQ7IH0g CiNkZWZpbmUgQ0hFQ0tfTlVMTChWQUxVRSwgTUVTU0FHRSwgUkVUKSBpZihWQUxVRSA9PSBOVUxM KSB7IGlmIChtYXhfY29uZmlnX2dldF9ib29sKE1BWF9DT05GSUdfU1RBVElDX0lOVEVSRkFDRV9B Qk9SVF9PTl9FUlJPUikpIHsgZnByaW50ZihzdGRlcnIsICIlc1xuJXNcbiIsIChzdG9yZWRfZXJy b3IgPT0gTlVMTCkgPyAiIiA6IHN0b3JlZF9lcnJvciwgTUVTU0FHRSk7IGFib3J0KCk7IH0gc2V0 X2Vycm9yKE1FU1NBR0UpOyByZXR1cm4gUkVUOyB9CgogCnR5cGVkZWYgc3RydWN0IFN0cmVhbUZN QV9jYWxsYmFja19zdHJlYW0gewoJdWludDhfdCAqdXNlcl9wdHI7Cgl1aW50OF90ICphbGlnbmVk X3B0cjsKCXNpemVfdCAgIHNpemU7CglpbnQgICAgICBpc19vdXRwdXQ7Cn0gU3RyZWFtRk1BX2Nh bGxiYWNrX3N0cmVhbV90OwoKdHlwZWRlZiBzdHJ1Y3QgU3RyZWFtRk1BX2NhbGxiYWNrX2RhdGEg ewoJU3RyZWFtRk1BX2NhbGxiYWNrX3N0cmVhbV90IHN0cmVhbVszXTsgCglpbnQgY291bnQ7Cglp bnQgbWF4X2NvdW50Owp9IFN0cmVhbUZNQV9jYWxsYmFja19kYXRhX3Q7CgpzdGF0aWMgdm9pZCBT dHJlYW1GTUFfY2FsbGJhY2tfaW50ZXJuYWwodm9pZCAqY2JfZGF0YSkKewoJU3RyZWFtRk1BX2Nh bGxiYWNrX2RhdGFfdCAqZGF0YSA9IChTdHJlYW1GTUFfY2FsbGJhY2tfZGF0YV90KikgY2JfZGF0 YTsKCWZvciAoaW50IGkgPSAwIDsgaSA8IGRhdGEtPmNvdW50IDsgaSsrICkgewoJCVN0cmVhbUZN QV9jYWxsYmFja19zdHJlYW1fdCAqcyA9ICZkYXRhLT5zdHJlYW1baV07CgkJaWYgKHMtPmlzX291 dHB1dCAmJiAocy0+c2l6ZSA+IDApKSB7CgkJCW1lbWNweShzLT51c2VyX3B0ciwgcy0+YWxpZ25l ZF9wdHIsIHMtPnNpemUpOwoJCX0KCQlmcmVlKHMtPmFsaWduZWRfcHRyKTsKCX0KCWZyZWUoZGF0 YSk7Cn0KCnN0YXRpYyBtYXhfYWN0aW9uc190KiBTdHJlYW1GTUFfY29udmVydF9pbnRlcm5hbCgK CW1heF9maWxlX3QgKm1heGZpbGUsCglTdHJlYW1GTUFfYWN0aW9uc190ICppbnRlcmZhY2VfYWN0 aW9ucywKCWludCAgaXNfaW50ZXJuYWxfY2FsbCwKCXZvaWQgKCoqY2FsbGJhY2tfZnVuYykodm9p ZCopLAoJdm9pZCAqKmNhbGxiYWNrX2RhdGEpCnsKCW1heF9hY3Rpb25zX3QgKmFjdGlvbnMgPSBt YXhfYWN0aW9uc19pbml0KG1heGZpbGUsIE5VTEwpOwoJaWYoYWN0aW9ucyA9PSBOVUxMKSByZXR1 cm4gTlVMTDsKCiNkZWZpbmUgQ0hFQ0tfRVJST1JTIGlmKCFtYXhfb2soYWN0aW9ucy0+ZXJyb3Jz KSkgeyBzZXRfZXJyb3JfYW5kX2ZyZWUobWF4X2Vycm9yc190cmFjZShhY3Rpb25zLT5lcnJvcnMp KTsgcmV0dXJuIE5VTEw7IH0gCgoJU3RyZWFtRk1BX2NhbGxiYWNrX2RhdGFfdCAqY2JfZGF0YSA9 IE5VTEw7CglpbnQgdXNlX2NhbGxiYWNrID0gKGNhbGxiYWNrX2Z1bmMgIT0gTlVMTCkgJiYgKGNh bGxiYWNrX2RhdGEgIT0gTlVMTCk7CglpZiAodXNlX2NhbGxiYWNrKSB7CgkJY2JfZGF0YSA9IG1h bGxvYyhzaXplb2YoU3RyZWFtRk1BX2NhbGxiYWNrX2RhdGFfdCkpOwoJCWlmIChjYl9kYXRhID09 IE5VTEwpIHsKCQkJZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gYWxsb2NhdGUgbWVtb3J5IGZv ciBzdHJlYW0gY2FsbGJhY2sgZGF0YSBpbiBmdW5jdGlvbiBTdHJlYW1GTUFfY29udmVydF9pbnRl cm5hbFxuIik7CgkJCXJldHVybiBOVUxMOwoJCX0KCQljYl9kYXRhLT5tYXhfY291bnQgPSAzOwoJ CWNiX2RhdGEtPmNvdW50ICAgICA9IDA7CgkJKmNhbGxiYWNrX2RhdGEgICAgID0gY2JfZGF0YTsK CQkqY2FsbGJhY2tfZnVuYyAgICAgPSAmU3RyZWFtRk1BX2NhbGxiYWNrX2ludGVybmFsOwoJfQoK CS8qIGNvZGUgZm9yIHNjYWxhciBTdHJlYW1GTUFLZXJuZWwucnVuX2N5Y2xlX2NvdW50ICovCgl1 aW50NjRfdCB0aWNrc19TdHJlYW1GTUFLZXJuZWwgPSBpbnRlcmZhY2VfYWN0aW9ucy0+dGlja3Nf U3RyZWFtRk1BS2VybmVsOwoJbWF4X3NldF90aWNrcyhhY3Rpb25zLCAiU3RyZWFtRk1BS2VybmVs IiwgdGlja3NfU3RyZWFtRk1BS2VybmVsKTsKCUNIRUNLX0VSUk9SUzsKCS8qIGVuZCBvZiBjb2Rl IGZvciBzY2FsYXIgU3RyZWFtRk1BS2VybmVsLnJ1bl9jeWNsZV9jb3VudCovCgkKCS8qIGNvZGUg Zm9yIHN0cmVhbSBhICovCglzaXplX3QgaW5zdHJlYW1fc2l6ZV9hID0gaW50ZXJmYWNlX2FjdGlv bnMtPmluc3RyZWFtX3NpemVfYTsKCWlmIChpbnN0cmVhbV9zaXplX2EgPiAwKSB7CgkJY29uc3Qg dm9pZCAqc3RyZWFtX3B0ciA9IGludGVyZmFjZV9hY3Rpb25zLT5pbnN0cmVhbV9hOwoJCWlmICh1 c2VfY2FsbGJhY2sgJiYgKDEgPT0gU3RyZWFtRk1BX2NoZWNrX2FsaWduZWQoaW50ZXJmYWNlX2Fj dGlvbnMtPmluc3RyZWFtX2EpKSkgewoJCQl2b2lkICphbGlnbmVkX2luc3RyZWFtX2EgPSBtYWxs b2MoaW5zdHJlYW1fc2l6ZV9hKTsKCQkJaWYgKGFsaWduZWRfaW5zdHJlYW1fYSA9PSBOVUxMKSB7 CgkJCQltYXhfcmVwb3J0X2Vycm9yX3NsaWMoYWN0aW9ucy0+ZXJyb3JzLCBfX0ZJTEVfXywgX19M SU5FX18sIDUyNiwgIkZhaWxlZCB0byBhbGxvY2F0ZSBhbGlnbmVkIG1lbW9yeSBmb3Igc3RyZWFt ICdhJyIpOwoJCQkJQ0hFQ0tfRVJST1JTOwoJCQl9CgkJCSgmY2JfZGF0YS0+c3RyZWFtW2NiX2Rh dGEtPmNvdW50XSktPnVzZXJfcHRyICAgID0gKHVpbnQ4X3QqKSBpbnRlcmZhY2VfYWN0aW9ucy0+ aW5zdHJlYW1fYTsKCQkJKCZjYl9kYXRhLT5zdHJlYW1bY2JfZGF0YS0+Y291bnRdKS0+YWxpZ25l ZF9wdHIgPSAodWludDhfdCopIGFsaWduZWRfaW5zdHJlYW1fYTsKCQkJKCZjYl9kYXRhLT5zdHJl YW1bY2JfZGF0YS0+Y291bnRdKS0+c2l6ZSAgICAgICAgPSBpbnN0cmVhbV9zaXplX2E7CgkJCSgm Y2JfZGF0YS0+c3RyZWFtW2NiX2RhdGEtPmNvdW50XSktPmlzX291dHB1dCAgID0gMDsKCQkJY2Jf ZGF0YS0+Y291bnQgKz0gMTsKCQkJbWVtY3B5KGFsaWduZWRfaW5zdHJlYW1fYSwgaW50ZXJmYWNl X2FjdGlvbnMtPmluc3RyZWFtX2EsIGluc3RyZWFtX3NpemVfYSk7CgkJCXN0cmVhbV9wdHIgPSBh bGlnbmVkX2luc3RyZWFtX2E7CgkJfQoJCW1heF9xdWV1ZV9pbnB1dChhY3Rpb25zLCAiYSIsIHN0 cmVhbV9wdHIsIGluc3RyZWFtX3NpemVfYSk7CgkJQ0hFQ0tfRVJST1JTOwoJfQoJLyogZW5kIG9m IGNvZGUgZm9yIHN0cmVhbSBhICovCgkKCS8qIGNvZGUgZm9yIHN0cmVhbSBiICovCglzaXplX3Qg aW5zdHJlYW1fc2l6ZV9iID0gaW50ZXJmYWNlX2FjdGlvbnMtPmluc3RyZWFtX3NpemVfYjsKCWlm IChpbnN0cmVhbV9zaXplX2IgPiAwKSB7CgkJY29uc3Qgdm9pZCAqc3RyZWFtX3B0ciA9IGludGVy ZmFjZV9hY3Rpb25zLT5pbnN0cmVhbV9iOwoJCWlmICh1c2VfY2FsbGJhY2sgJiYgKDEgPT0gU3Ry ZWFtRk1BX2NoZWNrX2FsaWduZWQoaW50ZXJmYWNlX2FjdGlvbnMtPmluc3RyZWFtX2IpKSkgewoJ CQl2b2lkICphbGlnbmVkX2luc3RyZWFtX2IgPSBtYWxsb2MoaW5zdHJlYW1fc2l6ZV9iKTsKCQkJ aWYgKGFsaWduZWRfaW5zdHJlYW1fYiA9PSBOVUxMKSB7CgkJCQltYXhfcmVwb3J0X2Vycm9yX3Ns aWMoYWN0aW9ucy0+ZXJyb3JzLCBfX0ZJTEVfXywgX19MSU5FX18sIDUyNiwgIkZhaWxlZCB0byBh bGxvY2F0ZSBhbGlnbmVkIG1lbW9yeSBmb3Igc3RyZWFtICdiJyIpOwoJCQkJQ0hFQ0tfRVJST1JT OwoJCQl9CgkJCSgmY2JfZGF0YS0+c3RyZWFtW2NiX2RhdGEtPmNvdW50XSktPnVzZXJfcHRyICAg ID0gKHVpbnQ4X3QqKSBpbnRlcmZhY2VfYWN0aW9ucy0+aW5zdHJlYW1fYjsKCQkJKCZjYl9kYXRh LT5zdHJlYW1bY2JfZGF0YS0+Y291bnRdKS0+YWxpZ25lZF9wdHIgPSAodWludDhfdCopIGFsaWdu ZWRfaW5zdHJlYW1fYjsKCQkJKCZjYl9kYXRhLT5zdHJlYW1bY2JfZGF0YS0+Y291bnRdKS0+c2l6 ZSAgICAgICAgPSBpbnN0cmVhbV9zaXplX2I7CgkJCSgmY2JfZGF0YS0+c3RyZWFtW2NiX2RhdGEt PmNvdW50XSktPmlzX291dHB1dCAgID0gMDsKCQkJY2JfZGF0YS0+Y291bnQgKz0gMTsKCQkJbWVt Y3B5KGFsaWduZWRfaW5zdHJlYW1fYiwgaW50ZXJmYWNlX2FjdGlvbnMtPmluc3RyZWFtX2IsIGlu c3RyZWFtX3NpemVfYik7CgkJCXN0cmVhbV9wdHIgPSBhbGlnbmVkX2luc3RyZWFtX2I7CgkJfQoJ CW1heF9xdWV1ZV9pbnB1dChhY3Rpb25zLCAiYiIsIHN0cmVhbV9wdHIsIGluc3RyZWFtX3NpemVf Yik7CgkJQ0hFQ0tfRVJST1JTOwoJfQoJLyogZW5kIG9mIGNvZGUgZm9yIHN0cmVhbSBiICovCgkK CS8qIGNvZGUgZm9yIHN0cmVhbSBvdXRwdXQgKi8KCXNpemVfdCBvdXRzdHJlYW1fc2l6ZV9vdXRw dXQgPSBpbnRlcmZhY2VfYWN0aW9ucy0+b3V0c3RyZWFtX3NpemVfb3V0cHV0OwoJaWYgKG91dHN0 cmVhbV9zaXplX291dHB1dCA+IDApIHsKCQl2b2lkICpzdHJlYW1fcHRyID0gaW50ZXJmYWNlX2Fj dGlvbnMtPm91dHN0cmVhbV9vdXRwdXQ7CgkJaWYgKHVzZV9jYWxsYmFjayAmJiAoMSA9PSBTdHJl YW1GTUFfY2hlY2tfYWxpZ25lZChpbnRlcmZhY2VfYWN0aW9ucy0+b3V0c3RyZWFtX291dHB1dCkp KSB7CgkJCXZvaWQgKmFsaWduZWRfb3V0c3RyZWFtX291dHB1dCA9IG1hbGxvYyhvdXRzdHJlYW1f c2l6ZV9vdXRwdXQpOwoJCQlpZiAoYWxpZ25lZF9vdXRzdHJlYW1fb3V0cHV0ID09IE5VTEwpIHsK CQkJCW1heF9yZXBvcnRfZXJyb3Jfc2xpYyhhY3Rpb25zLT5lcnJvcnMsIF9fRklMRV9fLCBfX0xJ TkVfXywgNTI2LCAiRmFpbGVkIHRvIGFsbG9jYXRlIGFsaWduZWQgbWVtb3J5IGZvciBzdHJlYW0g J291dHB1dCciKTsKCQkJCUNIRUNLX0VSUk9SUzsKCQkJfQoJCQkoJmNiX2RhdGEtPnN0cmVhbVtj Yl9kYXRhLT5jb3VudF0pLT51c2VyX3B0ciAgICA9ICh1aW50OF90KikgaW50ZXJmYWNlX2FjdGlv bnMtPm91dHN0cmVhbV9vdXRwdXQ7CgkJCSgmY2JfZGF0YS0+c3RyZWFtW2NiX2RhdGEtPmNvdW50 XSktPmFsaWduZWRfcHRyID0gKHVpbnQ4X3QqKSBhbGlnbmVkX291dHN0cmVhbV9vdXRwdXQ7CgkJ CSgmY2JfZGF0YS0+c3RyZWFtW2NiX2RhdGEtPmNvdW50XSktPnNpemUgICAgICAgID0gb3V0c3Ry ZWFtX3NpemVfb3V0cHV0OwoJCQkoJmNiX2RhdGEtPnN0cmVhbVtjYl9kYXRhLT5jb3VudF0pLT5p c19vdXRwdXQgICA9IDE7CgkJCWNiX2RhdGEtPmNvdW50ICs9IDE7CgkJCXN0cmVhbV9wdHIgPSBh bGlnbmVkX291dHN0cmVhbV9vdXRwdXQ7CgkJfQoJCW1heF9xdWV1ZV9vdXRwdXQoYWN0aW9ucywg Im91dHB1dCIsIHN0cmVhbV9wdHIsIG91dHN0cmVhbV9zaXplX291dHB1dCk7CgkJQ0hFQ0tfRVJS T1JTOwoJfQoJLyogZW5kIG9mIGNvZGUgZm9yIHN0cmVhbSBvdXRwdXQgKi8KCQoJaWYgKHVzZV9j YWxsYmFjayAmJiBjYl9kYXRhLT5jb3VudCA9PSAwKSB7CgkJKmNhbGxiYWNrX2RhdGEgPSBOVUxM OwoJCSpjYWxsYmFja19mdW5jID0gTlVMTDsKCQlmcmVlKGNiX2RhdGEpOwoJfQoJcmV0dXJuIGFj dGlvbnM7CiN1bmRlZiBDSEVDS19FUlJPUlMKfQoKdm9pZCBTdHJlYW1GTUEoCgl1aW50NjRfdCB0 aWNrc19TdHJlYW1GTUFLZXJuZWwsCgljb25zdCB2b2lkICppbnN0cmVhbV9hLAoJc2l6ZV90IGlu c3RyZWFtX3NpemVfYSwKCWNvbnN0IHZvaWQgKmluc3RyZWFtX2IsCglzaXplX3QgaW5zdHJlYW1f c2l6ZV9iLAoJdm9pZCAqb3V0c3RyZWFtX291dHB1dCwKCXNpemVfdCBvdXRzdHJlYW1fc2l6ZV9v dXRwdXQpCnsKCSh2b2lkKSBwdGhyZWFkX29uY2UoJnNsaWNfYnNfaXNfaW5pdGlhbGlzZWQsIFN0 cmVhbUZNQV9zdGF0aWNfaW5pdCk7CglDSEVDS19OVUxMKHN0b3JlZF9tYXhmaWxlLCAiTWF4Zmls ZSB3YXMgbm90IGxvYWRlZCIsICk7CgltYXhfcnVuX3QgKnJ1biA9IFN0cmVhbUZNQV9ub25ibG9j ayh0aWNrc19TdHJlYW1GTUFLZXJuZWwsIGluc3RyZWFtX2EsIGluc3RyZWFtX3NpemVfYSwgaW5z dHJlYW1fYiwgaW5zdHJlYW1fc2l6ZV9iLCBvdXRzdHJlYW1fb3V0cHV0LCBvdXRzdHJlYW1fc2l6 ZV9vdXRwdXQpOwoJQ0hFQ0tfTlVMTChydW4sICJVbmFibGUgdG8gcnVuIGFjdGlvbnMiLCApOwoJ bWF4X3dhaXQocnVuKTsKfQoKbWF4X3J1bl90ICpTdHJlYW1GTUFfbm9uYmxvY2soCgl1aW50NjRf dCB0aWNrc19TdHJlYW1GTUFLZXJuZWwsCgljb25zdCB2b2lkICppbnN0cmVhbV9hLAoJc2l6ZV90 IGluc3RyZWFtX3NpemVfYSwKCWNvbnN0IHZvaWQgKmluc3RyZWFtX2IsCglzaXplX3QgaW5zdHJl YW1fc2l6ZV9iLAoJdm9pZCAqb3V0c3RyZWFtX291dHB1dCwKCXNpemVfdCBvdXRzdHJlYW1fc2l6 ZV9vdXRwdXQpCnsKCVN0cmVhbUZNQV9hY3Rpb25zX3QgaW50ZXJmYWNlX2FjdGlvbnM7CglpbnRl cmZhY2VfYWN0aW9ucy50aWNrc19TdHJlYW1GTUFLZXJuZWwgPSB0aWNrc19TdHJlYW1GTUFLZXJu ZWw7CglpbnRlcmZhY2VfYWN0aW9ucy5pbnN0cmVhbV9hID0gaW5zdHJlYW1fYTsKCWludGVyZmFj ZV9hY3Rpb25zLmluc3RyZWFtX3NpemVfYSA9IGluc3RyZWFtX3NpemVfYTsKCWludGVyZmFjZV9h Y3Rpb25zLmluc3RyZWFtX2IgPSBpbnN0cmVhbV9iOwoJaW50ZXJmYWNlX2FjdGlvbnMuaW5zdHJl YW1fc2l6ZV9iID0gaW5zdHJlYW1fc2l6ZV9iOwoJaW50ZXJmYWNlX2FjdGlvbnMub3V0c3RyZWFt X291dHB1dCA9IG91dHN0cmVhbV9vdXRwdXQ7CglpbnRlcmZhY2VfYWN0aW9ucy5vdXRzdHJlYW1f c2l6ZV9vdXRwdXQgPSBvdXRzdHJlYW1fc2l6ZV9vdXRwdXQ7Cgkodm9pZCkgcHRocmVhZF9vbmNl KCZzbGljX2JzX2lzX2luaXRpYWxpc2VkLCBTdHJlYW1GTUFfc3RhdGljX2luaXQpOwoJQ0hFQ0tf TlVMTChzdG9yZWRfbWF4ZmlsZSwgIk1heGZpbGUgd2FzIG5vdCBsb2FkZWQiLCBOVUxMKTsKCXZv aWQgKCpjYl9mdW5jKSh2b2lkKikgPSBOVUxMOwoJdm9pZCAgKmNiX2RhdGEgICAgICAgICA9IE5V TEw7CgltYXhfYWN0aW9uc190ICphY3Rpb25zID0gU3RyZWFtRk1BX2NvbnZlcnRfaW50ZXJuYWwo c3RvcmVkX21heGZpbGUsICZpbnRlcmZhY2VfYWN0aW9ucywgMSwgJmNiX2Z1bmMsICZjYl9kYXRh KTsKCUNIRUNLX05VTEwoYWN0aW9ucywgIlVuYWJsZSB0byBidWlsZCBhY3Rpb25zIiwgTlVMTCk7 CgltYXhfdmFsaWRhdGUoYWN0aW9ucyk7CglDSEVDS19FUlJPUlNfU1QoYWN0aW9ucywgTlVMTCk7 CglDSEVDS19FUlJPUlNfU1Qoc3RvcmVkX2VuZ2luZSwgTlVMTCk7CgltYXhfcnVuX3QgKnJ1bjsK CWlmIChjYl9mdW5jID09IE5VTEwpIHsKCQlydW4gPSBtYXhfcnVuX25vbmJsb2NrKHN0b3JlZF9l bmdpbmUsIGFjdGlvbnMpOwoJfSBlbHNlIHsKCQlydW4gPSBtYXhfcnVuX25vbmJsb2NrX3dpdGhf Y2Ioc3RvcmVkX2VuZ2luZSwgYWN0aW9ucywgY2JfZnVuYywgY2JfZGF0YSk7Cgl9CglDSEVDS19O VUxMKHJ1biwgIlVuYWJsZSB0byBydW4gYWN0aW9ucyIsIE5VTEwpOwoJQ0hFQ0tfRVJST1JTX1NU KGFjdGlvbnMsIE5VTEwpOwoJbWF4X2FjdGlvbnNfZnJlZShhY3Rpb25zKTsKCXJldHVybiBydW47 Cn0KCnZvaWQgU3RyZWFtRk1BX3J1bigKCW1heF9lbmdpbmVfdCAqZW5naW5lLAoJU3RyZWFtRk1B X2FjdGlvbnNfdCAqaW50ZXJmYWNlX2FjdGlvbnMpCnsKCW1heF9ydW5fdCAqcnVuID0gU3RyZWFt Rk1BX3J1bl9ub25ibG9jayhlbmdpbmUsIGludGVyZmFjZV9hY3Rpb25zKTsKCUNIRUNLX05VTEwo cnVuLCAiVW5hYmxlIHRvIHJ1biBhY3Rpb25zIiwgKTsKCW1heF93YWl0KHJ1bik7Cn0KCm1heF9y dW5fdCAqU3RyZWFtRk1BX3J1bl9ub25ibG9jaygKCW1heF9lbmdpbmVfdCAqZW5naW5lLAoJU3Ry ZWFtRk1BX2FjdGlvbnNfdCAqaW50ZXJmYWNlX2FjdGlvbnMpCnsKCW1heF9maWxlX3QgKm1heGZp bGUgPSBtYXhfZW5naW5lX2dldF9tYXhfZmlsZShlbmdpbmUpOyAKCXZvaWQgKCpjYl9mdW5jKSh2 b2lkKikgPSBOVUxMOwoJdm9pZCAgKmNiX2RhdGEgICAgICAgICA9IE5VTEw7CgltYXhfYWN0aW9u c190ICphY3Rpb25zID0gU3RyZWFtRk1BX2NvbnZlcnRfaW50ZXJuYWwobWF4ZmlsZSwgaW50ZXJm YWNlX2FjdGlvbnMsIDEsICZjYl9mdW5jLCAmY2JfZGF0YSk7CglDSEVDS19OVUxMKGFjdGlvbnMs ICJVbmFibGUgdG8gYnVpbGQgYWN0aW9ucyIsIE5VTEwpOwoJbWF4X3ZhbGlkYXRlKGFjdGlvbnMp OwoJQ0hFQ0tfRVJST1JTX1NUKGFjdGlvbnMsIE5VTEwpOwoJbWF4X3J1bl90ICpydW47CglpZiAo Y2JfZnVuYyA9PSBOVUxMKSB7CgkJcnVuID0gbWF4X3J1bl9ub25ibG9jayhlbmdpbmUsIGFjdGlv bnMpOwoJfSBlbHNlIHsKCQlydW4gPSBtYXhfcnVuX25vbmJsb2NrX3dpdGhfY2IoZW5naW5lLCBh Y3Rpb25zLCBjYl9mdW5jLCBjYl9kYXRhKTsKCX0KCUNIRUNLX05VTEwocnVuLCAiVW5hYmxlIHRv IHJ1biBhY3Rpb25zIiwgTlVMTCk7CgltYXhfYWN0aW9uc19mcmVlKGFjdGlvbnMpOwoJcmV0dXJu IHJ1bjsKfQoKCi8qKgogKiBcYnJpZWYgR3JvdXAgcnVuIGFkdmFuY2VkIHN0YXRpYyBmdW5jdGlv biBmb3IgdGhlIGludGVyZmFjZSAnZGVmYXVsdCcuCiAqIAogKiBccGFyYW0gW2luXSBncm91cCBH cm91cCB0byB1c2UuCiAqIFxwYXJhbSBbaW4sb3V0XSBpbnRlcmZhY2VfYWN0aW9ucyBBY3Rpb25z IHRvIHJ1bi4KICoKICogUnVuIHRoZSBhY3Rpb25zIG9uIHRoZSBmaXJzdCBkZXZpY2UgYXZhaWxh YmxlIGluIHRoZSBncm91cC4KICovCnZvaWQgU3RyZWFtRk1BX3J1bl9ncm91cChtYXhfZ3JvdXBf dCAqZ3JvdXAsIFN0cmVhbUZNQV9hY3Rpb25zX3QgKmludGVyZmFjZV9hY3Rpb25zKQp7CgltYXhf cnVuX3QgKnJ1biA9IFN0cmVhbUZNQV9ydW5fZ3JvdXBfbm9uYmxvY2soZ3JvdXAsIGludGVyZmFj ZV9hY3Rpb25zKTsKCUNIRUNLX05VTEwocnVuLCAiVW5hYmxlIHRvIHJ1biBhY3Rpb25zIiwgKTsK CW1heF93YWl0KHJ1bik7Cn0KCgovKioKICogXGJyaWVmIEdyb3VwIHJ1biBhZHZhbmNlZCBzdGF0 aWMgbm9uLWJsb2NraW5nIGZ1bmN0aW9uIGZvciB0aGUgaW50ZXJmYWNlICdkZWZhdWx0Jy4KICog CiAqCiAqIFNjaGVkdWxlIHRoZSBhY3Rpb25zIHRvIHJ1biBvbiB0aGUgZmlyc3QgZGV2aWNlIGF2 YWlsYWJsZSBpbiB0aGUgZ3JvdXAgYW5kIHJldHVybiBpbW1lZGlhdGVseS4KICogVGhlIHN0YXR1 cyBvZiB0aGUgcnVuIG11c3QgYmUgY2hlY2tlZCB3aXRoIDo6bWF4X3dhaXQuIAogKiBOb3RlIHRo YXQgdXNlIG9mIDo6bWF4X25vd2FpdCBpcyBwcm9oaWJpdGVkIHdpdGggbm9uLWJsb2NraW5nIHJ1 bm5pbmcgb24gZ3JvdXBzOgogKiBzZWUgdGhlIDo6bWF4X3J1bl9ncm91cF9ub25ibG9jayBkb2N1 bWVudGF0aW9uIGZvciBtb3JlIGV4cGxhbmF0aW9uLgogKgogKiBccGFyYW0gW2luXSBncm91cCBH cm91cCB0byB1c2UuCiAqIFxwYXJhbSBbaW5dIGludGVyZmFjZV9hY3Rpb25zIEFjdGlvbnMgdG8g cnVuLgogKiBccmV0dXJuIEEgaGFuZGxlIG9uIHRoZSBleGVjdXRpb24gc3RhdHVzIG9mIHRoZSBh Y3Rpb25zLCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IuCiAqLwptYXhfcnVuX3QgKlN0cmVhbUZN QV9ydW5fZ3JvdXBfbm9uYmxvY2sobWF4X2dyb3VwX3QgKmdyb3VwLCBTdHJlYW1GTUFfYWN0aW9u c190ICppbnRlcmZhY2VfYWN0aW9ucykKewoJbWF4X2ZpbGVfdCAqbWF4ZmlsZSA9IG1heF9ncm91 cF9nZXRfbWF4X2ZpbGUoZ3JvdXApOwoJbWF4X2FjdGlvbnNfdCAqYWN0aW9ucyA9IFN0cmVhbUZN QV9jb252ZXJ0X2ludGVybmFsKG1heGZpbGUsIGludGVyZmFjZV9hY3Rpb25zLCAxLCBOVUxMLCBO VUxMKTsKCWlmKGFjdGlvbnMgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CglpZighbWF4X29rKGFjdGlv bnMtPmVycm9ycykpIHJldHVybiBOVUxMOwoJbWF4X3ZhbGlkYXRlKGFjdGlvbnMpOwoJbWF4X3J1 bl90ICpydW4gPSBtYXhfcnVuX2dyb3VwX25vbmJsb2NrKGdyb3VwLCBhY3Rpb25zKTsKCW1heF9h Y3Rpb25zX2ZyZWUoYWN0aW9ucyk7CglyZXR1cm4gcnVuOwp9CgoKLyoqCiAqIFxicmllZiBBcnJh eSBydW4gYWR2YW5jZWQgc3RhdGljIGZ1bmN0aW9uIGZvciB0aGUgaW50ZXJmYWNlICdkZWZhdWx0 Jy4KICogCiAqIFxwYXJhbSBbaW5dIGVuZ2FycmF5IFRoZSBhcnJheSBvZiBkZXZpY2VzIHRvIHVz ZS4KICogXHBhcmFtIFtpbixvdXRdIGludGVyZmFjZV9hY3Rpb25zIFRoZSBhcnJheSBvZiBhY3Rp b25zIHRvIHJ1bi4KICoKICogUnVuIHRoZSBhcnJheSBvZiBhY3Rpb25zIG9uIHRoZSBhcnJheSBv ZiBlbmdpbmVzLiAgVGhlIGxlbmd0aCBvZiBpbnRlcmZhY2VfYWN0aW9ucwogKiBtdXN0IG1hdGNo IHRoZSBzaXplIG9mIGVuZ2FycmF5LgogKi8Kdm9pZCBTdHJlYW1GTUFfcnVuX2FycmF5KG1heF9l bmdhcnJheV90ICplbmdhcnJheSwgU3RyZWFtRk1BX2FjdGlvbnNfdCAqaW50ZXJmYWNlX2FjdGlv bnNbXSkKewoJbWF4X3J1bl90ICpydW4gPSBTdHJlYW1GTUFfcnVuX2FycmF5X25vbmJsb2NrKGVu Z2FycmF5LCBpbnRlcmZhY2VfYWN0aW9ucyk7CglDSEVDS19OVUxMKHJ1biwgIlVuYWJsZSB0byBy dW4gYWN0aW9ucyIsICk7CgltYXhfd2FpdChydW4pOwp9CgoKLyoqCiAqIFxicmllZiBBcnJheSBy dW4gYWR2YW5jZWQgc3RhdGljIG5vbi1ibG9ja2luZyBmdW5jdGlvbiBmb3IgdGhlIGludGVyZmFj ZSAnZGVmYXVsdCcuCiAqIAogKgogKiBTY2hlZHVsZSB0byBydW4gdGhlIGFycmF5IG9mIGFjdGlv bnMgb24gdGhlIGFycmF5IG9mIGVuZ2luZXMsIGFuZCByZXR1cm4gaW1tZWRpYXRlbHkuCiAqIFRo ZSBsZW5ndGggb2YgaW50ZXJmYWNlX2FjdGlvbnMgbXVzdCBtYXRjaCB0aGUgc2l6ZSBvZiBlbmdh cnJheS4KICogVGhlIHN0YXR1cyBvZiB0aGUgcnVuIGNhbiBiZSBjaGVja2VkIGVpdGhlciBieSA6 Om1heF93YWl0IG9yIDo6bWF4X25vd2FpdDsKICogbm90ZSB0aGF0IG9uZSBvZiB0aGVzZSAqbXVz dCogYmUgY2FsbGVkLCBzbyB0aGF0IGFzc29jaWF0ZWQgbWVtb3J5IGNhbiBiZSByZWxlYXNlZC4K ICoKICogXHBhcmFtIFtpbl0gZW5nYXJyYXkgVGhlIGFycmF5IG9mIGRldmljZXMgdG8gdXNlLgog KiBccGFyYW0gW2luXSBpbnRlcmZhY2VfYWN0aW9ucyBUaGUgYXJyYXkgb2YgYWN0aW9ucyB0byBy dW4uCiAqIFxyZXR1cm4gQSBoYW5kbGUgb24gdGhlIGV4ZWN1dGlvbiBzdGF0dXMgb2YgdGhlIGFj dGlvbnMsIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvci4KICovCm1heF9ydW5fdCAqU3RyZWFtRk1B X3J1bl9hcnJheV9ub25ibG9jayhtYXhfZW5nYXJyYXlfdCAqZW5nYXJyYXksIFN0cmVhbUZNQV9h Y3Rpb25zX3QgKmludGVyZmFjZV9hY3Rpb25zW10pCnsKCW1heF9maWxlX3QgKm1heGZpbGUgPSBt YXhfZW5nYXJyYXlfZ2V0X21heF9maWxlKGVuZ2FycmF5LCAwKTsKCWludCBpOwoJbWF4X2FjdGFy cmF5X3QgKmFjdGFycmF5ID0gbWF4X2FjdGFycmF5X2luaXQobWF4ZmlsZSwgZW5nYXJyYXktPnNp emUpOwoJaWYgKGFjdGFycmF5ID09IE5VTEwpIHJldHVybiBOVUxMOwoJbWF4X2FjdGlvbnNfdCAq KmFycl9hY3Rpb25zID0gbWFsbG9jKGVuZ2FycmF5LT5zaXplICogc2l6ZW9mKG1heF9hY3Rpb25z X3QqKSk7Cglmb3IgKCBpID0gMCA7IGkgPCBhY3RhcnJheS0+c2l6ZTsgaSsrICkgewoJCW1heF9h Y3Rpb25zX3QgKmFjdGlvbnMgPSBTdHJlYW1GTUFfY29udmVydF9pbnRlcm5hbChtYXhmaWxlLCBp bnRlcmZhY2VfYWN0aW9uc1tpXSwgMSwgTlVMTCwgTlVMTCk7CgkJaWYgKGFjdGlvbnMgPT0gTlVM TCkgcmV0dXJuIE5VTEw7CgkJYXJyX2FjdGlvbnNbaV0gPSBhY3Rpb25zOwoJCW1heF9zZXRfYWN0 aW9uKGFjdGFycmF5LCBpLCBhY3Rpb25zKTsKCX0KCW1heF9ydW5fdCAqcnVuID0gbWF4X3J1bl9h cnJheV9ub25ibG9jayhlbmdhcnJheSwgYWN0YXJyYXkpOwoJZm9yICggaSA9IDAgOyBpIDwgYWN0 YXJyYXktPnNpemUgOyBpKysgKSB7IG1heF9hY3Rpb25zX2ZyZWUoYXJyX2FjdGlvbnNbaV0pOyB9 CgltYXhfYWN0YXJyYXlfZnJlZShhY3RhcnJheSk7CglmcmVlKGFycl9hY3Rpb25zKTsKCXJldHVy biBydW47Cn0KCgovKioKICogXGJyaWVmIENvbnZlcnRzIGEgc3RhdGljLWludGVyZmFjZSBhY3Rp b24gc3RydWN0IGludG8gYSBkeW5hbWljLWludGVyZmFjZSBtYXhfYWN0aW9uc190IHN0cnVjdC4K ICoKICogTm90ZSB0aGF0IHRoaXMgaXMgYW4gaW50ZXJuYWwgdXRpbGl0eSBmdW5jdGlvbiB1c2Vk IGJ5IG90aGVyIGZ1bmN0aW9ucyBpbiB0aGUgc3RhdGljIGludGVyZmFjZS4KICoKICogXHBhcmFt IFtpbl0gbWF4ZmlsZSBUaGUgbWF4ZmlsZSB0byB1c2UuCiAqIFxwYXJhbSBbaW5dIGludGVyZmFj ZV9hY3Rpb25zIFRoZSBpbnRlcmZhY2Utc3BlY2lmaWMgYWN0aW9ucyB0byBydW4uCiAqIFxyZXR1 cm4gVGhlIGR5bmFtaWMtaW50ZXJmYWNlIGFjdGlvbnMgdG8gcnVuLCBvciBOVUxMIGluIGNhc2Ug b2YgZXJyb3IuCiAqLwptYXhfYWN0aW9uc190KiBTdHJlYW1GTUFfY29udmVydChtYXhfZmlsZV90 ICptYXhmaWxlLCBTdHJlYW1GTUFfYWN0aW9uc190ICppbnRlcmZhY2VfYWN0aW9ucykKewoJcmV0 dXJuIFN0cmVhbUZNQV9jb252ZXJ0X2ludGVybmFsKG1heGZpbGUsIGludGVyZmFjZV9hY3Rpb25z LCAwLCBOVUxMLCBOVUxMKTsKfQoKI3VuZGVmIENIRUNLX0VSUk9SU19TVAojdW5kZWYgQ0hFQ0tf TlVMTAoKCg== #endif /* SLIC_B64_DEFINITIONS */ #ifdef SLIC_EXTRA_FILES PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHVz ZXJmaWxlcyBmb3JtYXQtdmVyc2lvbj0iMjAxMjAyMDAiLz4= #endif /* SLIC_EXTRA_FILES */ #ifdef PHOTON_NODE_ADD_DATA #define PHOTON_NODE_ADD_DATA_PRESENT 1 PHOTON_NODE_ADD_DATA(StreamFMAKernel, 8, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 9, "SquashFactor", 1.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 0, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 1, "SquashFactor", 1.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 2, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 3, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 4, "SquashFactor", 1.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 5, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 6, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 11, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 16, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 26, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 13, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 14, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 15, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 17, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 25, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 19, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 20, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 22, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 24, "SquashFactor", 0.0) PHOTON_NODE_ADD_DATA(StreamFMAKernel, 21, "SquashFactor", 0.0) #endif #ifdef MAXFILE_SIGNATURE #define MAXFILE_SIGNATURE_PRESENT 1 MAXFILE_SIGNATURE("302c02143578f5aee3b838f55f88f02510321eee5917f7ab021400efececa243f79c7dc512190b3fd86bf70d0c0f") #endif