• <xmp id="om0om">
  • <table id="om0om"><noscript id="om0om"></noscript></table>
  • Compute Graph Framework SDK Reference  5.8
    All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
    Port.hpp
    Go to the documentation of this file.
    1
    2//
    3// Notice
    4// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
    5// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
    6// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
    7// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
    8//
    9// NVIDIA CORPORATION & AFFILIATES assumes no responsibility for the consequences of use of such
    10// information or for any infringement of patents or other rights of third parties that may
    11// result from its use. No license is granted by implication or otherwise under any patent
    12// or patent rights of NVIDIA CORPORATION & AFFILIATES. No third party distribution is allowed unless
    13// expressly authorized by NVIDIA. Details are subject to change without notice.
    14// This code supersedes and replaces all information previously supplied.
    15// NVIDIA CORPORATION & AFFILIATES products are not authorized for use as critical
    16// components in life support devices or systems without express written approval of
    17// NVIDIA CORPORATION & AFFILIATES.
    18//
    19// SPDX-FileCopyrightText: Copyright (c) 2018-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
    20// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
    21//
    22// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
    23// property and proprietary rights in and to this material, related
    24// documentation and any modifications thereto. Any use, reproduction,
    25// disclosure or distribution of this material and related documentation
    26// without an express license agreement from NVIDIA CORPORATION or
    27// its affiliates is strictly prohibited.
    28//
    30
    31#ifndef DW_FRAMEWORK_PORT_H_
    32#define DW_FRAMEWORK_PORT_H_
    33
    35
    36#include "SyncPortHelper.hpp"
    37
    38#include <stdexcept>
    39#include <string>
    40
    41namespace dw
    42{
    43namespace framework
    44{
    45
    47enum class PortDirection : uint8_t
    48{
    49 INPUT = 0,
    50 OUTPUT,
    51 COUNT,
    52};
    53
    55{
    56public:
    57 virtual ~PortBase() = default;
    58};
    59
    61class Port : public PortBase
    62{
    63public:
    64 virtual dwStatus bindChannel(ChannelObject* channel) = 0;
    65 virtual dwStatus initialize() { return DW_SUCCESS; }
    66 virtual bool isBound() = 0;
    67};
    68
    70
    77template <typename T>
    78class PortOutput : public SyncPortHelperOutput<T>, public Port
    79{
    80public:
    82 using ApiDataTypeT = T;
    85
    86 static_assert(std::is_copy_constructible<SpecimenT>::value, "SpecimenT is not copy constructible");
    87
    88 static constexpr char LOG_TAG[] = "PortOutput";
    89
    90private:
    91 ChannelObject::Producer* m_channelProducer{};
    92 SpecimenT m_reference{};
    93 OnSetSyncAttrs m_waiterAttrs{};
    94 OnSetSyncAttrs m_signalerAttrs{};
    95
    96public:
    97 explicit PortOutput(SpecimenT const& ref)
    98 : m_reference(ref)
    99 {
    100 }
    101 explicit PortOutput(SpecimenT&& ref)
    102 : m_reference(std::move(ref))
    103 {
    104 }
    105
    106 explicit PortOutput(SpecimenT const& ref,
    107 OnSetSyncAttrs signalerAttrs,
    108 OnSetSyncAttrs waiterAttrs = {})
    109 : m_reference(ref)
    110 , m_waiterAttrs(waiterAttrs)
    111 , m_signalerAttrs(signalerAttrs)
    112 {
    113 }
    114
    115 // Channel Bind
    116 dwStatus bindChannel(ChannelObject* channel) override
    117 {
    118 auto ref = make_specimen<T>(&m_reference);
    119 return bindChannelWithReference(channel, ref);
    120 }
    121
    123 {
    124 return Exception::guard([&] {
    125 if (isBound())
    126 {
    127 // TODO(chale): this should be an Exception but applications are currently
    128 // doing this. Those applications should be fixed.
    129 FRWK_LOGE << "PortOutput: bindChannel: attempted to bind the same port twice, ignoring this bind!" << Logger::State::endl;
    130 return;
    131 }
    132 if (channel == nullptr)
    133 {
    134 throw Exception(DW_INVALID_ARGUMENT, "PortOutput: bindChannel: expected channel != nullptr");
    135 }
    136
    138
    140 {
    142 }
    143
    144 ref.setWaiterAttributes = m_waiterAttrs;
    145 ref.setSignalerAttributes = m_signalerAttrs;
    146
    147 m_channelProducer = channel->getProducer(ref);
    148 if (m_channelProducer == nullptr)
    149 {
    150 throw Exception(DW_INTERNAL_ERROR, "PortOutput bindChannel: wrong channel implementations returned.");
    151 }
    152 });
    153 }
    154
    156 {
    157 if (!isBound())
    158 {
    159 throw Exception(DW_NOT_AVAILABLE, "PortOutput: setOnDataReady: no bound channel");
    160 }
    161 m_channelProducer->setOnDataReady(opaque, onDataReady);
    162 }
    163
    164 bool isBound() final
    165 {
    166 return (m_channelProducer != nullptr);
    167 }
    168
    169 dwStatus wait(dwTime_t timeout)
    170 {
    171 if (!isBound())
    172 {
    173 throw Exception(DW_NOT_AVAILABLE, "PortInput: wait: no bound channel");
    174 }
    175
    176 return m_channelProducer->wait(timeout);
    177 }
    178
    179 // Node accessors
    180 // TODO(unknown): This function's prototype needs to change to properly propagate errors
    182 {
    183 dwStatus status = DW_FAILURE;
    184 GenericData genericData{};
    185 if (m_channelProducer)
    186 {
    187 status = m_channelProducer->get(&genericData);
    188 }
    189
    190 if (status != DW_SUCCESS)
    191 {
    192 return nullptr;
    193 }
    194
    196 {
    197 return BaseSyncHelper::extractInternalPacket(genericData);
    198 }
    199
    200 return genericData.template getData<T>();
    201 }
    202
    203 // Tx Operations
    204 virtual dwStatus send(T* frame)
    205 {
    206 if (!m_channelProducer)
    207 {
    208 throw Exception(DW_NOT_AVAILABLE, "PortOutput: channel not bound");
    209 }
    210
    212 {
    213 return m_channelProducer->send(BaseSyncHelper::getSyncPacket(frame));
    214 }
    215
    216 return m_channelProducer->send(frame);
    217 }
    218
    220 {
    221 if (!m_channelProducer)
    222 {
    223 throw Exception(DW_NOT_AVAILABLE, "PortOutput: channel not bound");
    224 }
    225 return m_channelProducer->getSyncSignaler();
    226 }
    227
    228 void setSignalFences(T* frame, dw::core::span<NvSciSyncFence> fences)
    229 {
    231 {
    232 m_channelProducer->getSyncSignaler().setSignalFences(BaseSyncHelper::getSyncPacket(frame), fences);
    233 }
    234 else
    235 {
    236 m_channelProducer->getSyncSignaler().setSignalFences(frame, fences);
    237 }
    238 }
    239
    241 {
    242 if (!m_channelProducer)
    243 {
    244 throw Exception(DW_NOT_AVAILABLE, "PortOutput: channel not bound");
    245 }
    246 return m_channelProducer->getSyncWaiter();
    247 }
    248
    249 void getWaitFences(T* frame, dw::core::span<NvSciSyncFence> fences)
    250 {
    252 {
    253 m_channelProducer->getSyncWaiter().getWaitFences(BaseSyncHelper::getSyncPacket(frame), fences);
    254 }
    255 else
    256 {
    257 m_channelProducer->getSyncWaiter().getWaitFences(frame, fences);
    258 }
    259 }
    260};
    261
    262template <typename T>
    263constexpr char PortOutput<T>::LOG_TAG[];
    264
    266
    273template <typename T>
    274class PortInput : public SyncPortHelperInput<T>, public Port
    275{
    276 static constexpr char LOG_TAG[] = "PortInput";
    277
    278public:
    280 using ApiDataTypeT = T;
    283
    284 static_assert(std::is_copy_constructible<SpecimenT>::value, "SpecimenT is not copy constructible");
    285
    286 explicit PortInput(SpecimenT const& ref)
    287 : m_reference(ref)
    288 {
    289 }
    290 explicit PortInput(SpecimenT&& ref)
    291 : m_reference(std::move(ref))
    292 {
    293 }
    294
    296 {
    297 }
    298
    299 explicit PortInput(OnSetSyncAttrs waiterAttrs,
    300 OnSetSyncAttrs signalerAttrs = {})
    301 : m_waiterAttrs(waiterAttrs)
    302 , m_signalerAttrs(signalerAttrs)
    303 {
    304 }
    305
    306 explicit PortInput(SpecimenT const& ref,
    307 OnSetSyncAttrs waiterAttrs,
    308 OnSetSyncAttrs signalerAttrs = {})
    309 : m_reference(ref)
    310 , m_waiterAttrs(waiterAttrs)
    311 , m_signalerAttrs(signalerAttrs)
    312 {
    313 }
    314
    315 ~PortInput() override = default;
    316
    317 // Channel Bind
    318 dwStatus bindChannel(ChannelObject* channel) override
    319 {
    320 return Exception::guard([&] {
    321 if (isBound())
    322 {
    323 // TODO(chale): this should be an Exception but applications are currently
    324 // doing this. Those applications should be fixed.
    325 FRWK_LOGE << "PortInput: bindChannel: attempted to bind the same port twice, ignoring this bind!" << Logger::State::endl;
    326 return;
    327 }
    328 if (channel == nullptr)
    329 {
    330 throw Exception(DW_INVALID_ARGUMENT, "PortInput: bindChannel: expected channel != nullptr");
    331 }
    332
    334 auto ref = make_specimen<T>(nullptr);
    335
    336 if (m_reference)
    337 {
    338 ref = make_specimen<T>(&m_reference.value());
    339 }
    340
    342 {
    343 ref.packetTypeID = BaseSyncHelper::getNewPacketID(ref.packetTypeID);
    344 }
    345
    346 ref.setWaiterAttributes = m_waiterAttrs;
    347 ref.setSignalerAttributes = m_signalerAttrs;
    348
    349 m_channelConsumer = channel->getConsumer(ref);
    350 if (m_channelConsumer == nullptr)
    351 {
    352 throw Exception(DW_INTERNAL_ERROR, "PortInput bindChannel: wrong channel implementations returned.");
    353 }
    354 m_reuse = channel->getParams().getReuseEnabled();
    355 });
    356 }
    357
    358 bool isBound() override
    359 {
    360 return !(m_channelConsumer == nullptr);
    361 }
    362
    364 {
    365 if (!isBound())
    366 {
    367 throw Exception(DW_NOT_AVAILABLE, "PortInput: setOnDataReady: no bound channel");
    368 }
    369 m_channelConsumer->setOnDataReady(opaque, onDataReady);
    370 }
    371
    372 // Rx Operations
    373 dwStatus wait(dwTime_t timeout)
    374 {
    375 if (!isBound())
    376 {
    377 throw Exception(DW_NOT_AVAILABLE, "PortInput: wait: no bound channel");
    378 }
    379
    380 // For synced packets, the wait can return DW_NOT_AVAILABLE or DW_SUCCESS
    381 // if there are no packets to consume. This is because you need to consume
    382 // a packet to make sure it's valid or not.
    384 {
    385 return DW_SUCCESS;
    386 }
    388 {
    389 return DW_NOT_AVAILABLE;
    390 }
    392 {
    393 timeout = 0;
    394 }
    395
    396 dwTime_t waitTime = m_last ? 0 : timeout;
    397 dwStatus status = m_channelConsumer->wait(waitTime);
    398 if (m_last && (status == DW_TIME_OUT || status == DW_NOT_AVAILABLE))
    399 {
    400 return DW_SUCCESS;
    401 }
    402
    403 return status;
    404 }
    405
    406 // TODO(unknown): This function's prototype needs to change to properly propagate errors
    407 virtual std::shared_ptr<T> recv()
    408 {
    410 std::shared_ptr<T> result;
    411 if (!isBound())
    412 {
    413 return nullptr;
    414 }
    415
    416 T* typedData = nullptr;
    417 void* releasePtr = nullptr;
    418
    420 {
    421 // There is a valid packet to consume
    423 releasePtr = data.getPointer();
    425 }
    427 {
    428 // There is a buffered packet, but it's not ready to be consumed.
    429 return nullptr;
    430 }
    431 else
    432 {
    433 dwStatus status = m_channelConsumer->recv(&data);
    434 if (status != DW_SUCCESS)
    435 {
    436 if (m_last != nullptr)
    437 {
    438 return m_last;
    439 }
    440 else
    441 {
    442 return nullptr;
    443 }
    444 }
    445 releasePtr = data.getPointer();
    446
    448 {
    450 if (!typedData)
    451 {
    452 return nullptr;
    453 }
    454 }
    455 else
    456 {
    457 typedData = data.template getData<T>();
    458 }
    459 }
    460
    461 // don't rely on this class's member when releasing packet
    462 auto* channelConsumer = m_channelConsumer;
    463 result = std::shared_ptr<T>(typedData, [channelConsumer, releasePtr](T*) {
    464 channelConsumer->release(releasePtr);
    465 });
    466 if (m_reuse)
    467 {
    468 m_last = result;
    469 }
    470
    471 return result;
    472 }
    473
    475 {
    476 if (!m_channelConsumer)
    477 {
    478 throw Exception(DW_NOT_AVAILABLE, "PortInput: channel not bound");
    479 }
    480 return m_channelConsumer->getSyncSignaler();
    481 }
    482
    483 void setSignalFences(T* frame, dw::core::span<NvSciSyncFence> fences)
    484 {
    486 {
    487 throw Exception(DW_NOT_SUPPORTED, "PortInput: not supported");
    488 }
    489 else
    490 {
    491 m_channelConsumer->getSyncSignaler().setSignalFences(frame, fences);
    492 }
    493 }
    494
    496 {
    497 if (!m_channelConsumer)
    498 {
    499 throw Exception(DW_NOT_AVAILABLE, "PortInput: channel not bound");
    500 }
    501 return m_channelConsumer->getSyncWaiter();
    502 }
    503
    504 void getWaitFences(T* frame, dw::core::span<NvSciSyncFence> fences)
    505 {
    507 {
    508 throw Exception(DW_NOT_SUPPORTED, "PortInput: not supported");
    509 }
    510 else
    511 {
    512 m_channelConsumer->getSyncWaiter().getWaitFences(frame, fences);
    513 }
    514 }
    515
    516private:
    517 ChannelObject::Consumer* m_channelConsumer{};
    518 bool m_reuse{};
    519 std::shared_ptr<T> m_last{};
    520 dw::core::Optional<SpecimenT> m_reference{};
    521 OnSetSyncAttrs m_waiterAttrs{};
    522 OnSetSyncAttrs m_signalerAttrs{};
    523};
    524
    525template <typename T>
    526constexpr char PortInput<T>::LOG_TAG[];
    527
    528} // namespace framework
    529} // namespace dw
    530
    531#endif // DW_FRAMEWORK_PORT_H_
    #define FRWK_LOGE
    Definition: Logger.hpp:41
    virtual dwStatus recv(GenericData *data)=0
    virtual dwStatus wait(dwTime_t timeout)=0
    virtual void setOnDataReady(void *opaque, OnDataReady onDataReady)=0
    dw::core::Function< void()> OnDataReady
    Definition: Channel.hpp:136
    virtual dwStatus get(GenericData *data)=0
    virtual dwStatus send(void *data)=0
    virtual void setSignalFences(void *data, dw::core::span< const NvSciSyncFence > postFences)=0
    virtual void getWaitFences(void *data, dw::core::span< NvSciSyncFence > &waitFences)=0
    virtual Producer * getProducer(GenericDataReference ref)=0
    virtual const ChannelParams & getParams() const =0
    virtual Consumer * getConsumer(GenericDataReference ref)=0
    static dwStatus guard(TryBlock tryBlock, dw::core::Logger::Verbosity verbosity=dw::core::Logger::Verbosity::DEBUG)
    Definition: Exception.hpp:228
    virtual ~PortBase()=default
    PortInput(OnSetSyncAttrs waiterAttrs, OnSetSyncAttrs signalerAttrs={})
    Definition: Port.hpp:299
    virtual std::shared_ptr< T > recv()
    Definition: Port.hpp:407
    dwStatus wait(dwTime_t timeout)
    Definition: Port.hpp:373
    ChannelObject::SyncSignaler & getSyncSignaler()
    Definition: Port.hpp:474
    PortInput(SpecimenT const &ref, OnSetSyncAttrs waiterAttrs, OnSetSyncAttrs signalerAttrs={})
    Definition: Port.hpp:306
    dwStatus bindChannel(ChannelObject *channel) override
    Definition: Port.hpp:318
    ChannelObject::SyncWaiter & getSyncWaiter()
    Definition: Port.hpp:495
    typename parameter_traits< T >::SpecimenT SpecimenT
    Definition: Port.hpp:281
    void setSignalFences(T *frame, dw::core::span< NvSciSyncFence > fences)
    Definition: Port.hpp:483
    bool isBound() override
    Definition: Port.hpp:358
    static constexpr PortDirection DIRECTION
    Definition: Port.hpp:279
    void setOnDataReady(void *opaque, ChannelObject::PacketPool::OnDataReady onDataReady)
    Definition: Port.hpp:363
    ~PortInput() override=default
    void getWaitFences(T *frame, dw::core::span< NvSciSyncFence > fences)
    Definition: Port.hpp:504
    PortInput(SpecimenT &&ref)
    Definition: Port.hpp:290
    PortInput(SpecimenT const &ref)
    Definition: Port.hpp:286
    dwStatus wait(dwTime_t timeout)
    Definition: Port.hpp:169
    static constexpr char LOG_TAG[]
    Definition: Port.hpp:88
    dwStatus bindChannelWithReference(ChannelObject *channel, GenericDataReference &ref)
    Definition: Port.hpp:122
    dwStatus bindChannel(ChannelObject *channel) override
    Definition: Port.hpp:116
    void setOnDataReady(void *opaque, ChannelObject::PacketPool::OnDataReady onDataReady)
    Definition: Port.hpp:155
    PortOutput(SpecimenT const &ref)
    Definition: Port.hpp:97
    typename parameter_traits< T >::SpecimenT SpecimenT
    Definition: Port.hpp:83
    ChannelObject::SyncSignaler & getSyncSignaler()
    Definition: Port.hpp:219
    bool isBound() final
    Definition: Port.hpp:164
    PortOutput(SpecimenT const &ref, OnSetSyncAttrs signalerAttrs, OnSetSyncAttrs waiterAttrs={})
    Definition: Port.hpp:106
    void setSignalFences(T *frame, dw::core::span< NvSciSyncFence > fences)
    Definition: Port.hpp:228
    ChannelObject::SyncWaiter & getSyncWaiter()
    Definition: Port.hpp:240
    void getWaitFences(T *frame, dw::core::span< NvSciSyncFence > fences)
    Definition: Port.hpp:249
    static constexpr PortDirection DIRECTION
    Definition: Port.hpp:81
    PortOutput(SpecimenT &&ref)
    Definition: Port.hpp:101
    virtual dwStatus send(T *frame)
    Definition: Port.hpp:204
    virtual dwStatus bindChannel(ChannelObject *channel)=0
    virtual bool isBound()=0
    virtual dwStatus initialize()
    Definition: Port.hpp:65
    T * extractInternalPacket(GenericData genericData)
    T * extractInternalPacket(GenericData genericData)
    SyncedPacketPayload * getSyncPacket(T *frame)
    void parseDataSynced(const ChannelParams &params) override
    dw::core::Function< void(NvSciSyncAttrList)> OnSetSyncAttrs
    dwCalibrationStatus status
    Definition: Exception.hpp:47
    ChannelPacketTypeID getNewPacketID(ChannelPacketTypeID packetTypeID)
    virtual void parseDataSynced(const ChannelParams &params)
    人人超碰97caoporen国产