diff --git a/superpoint/CMakeLists.txt b/superpoint/CMakeLists.txt
new file mode 100644
index 0000000..07e9a27
--- /dev/null
+++ b/superpoint/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 2.6)
+
+project(SuperPointNet)
+
+add_definitions(-std=c++11)
+
+option(CUDA_USE_STATIC_CUDA_RUNTIME OFF)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_BUILD_TYPE Debug)
+
+find_package(CUDA REQUIRED)
+
+include_directories(${PROJECT_SOURCE_DIR}/include)
+# include and link dirs of cuda and tensorrt, you need adapt them if yours are different
+# cuda
+include_directories(/usr/local/cuda/include)
+link_directories(/usr/local/cuda/lib64)
+# tensorrt
+include_directories(/usr/include/x86_64-linux-gnu/)
+link_directories(/usr/lib/x86_64-linux-gnu/)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread -Wall -Ofast -Wfatal-errors -D_MWAITXINTRIN_H_INCLUDED")
+
+find_package(OpenCV)
+include_directories(${OpenCV_INCLUDE_DIRS})
+
+add_executable(supernet ${PROJECT_SOURCE_DIR}/supernet.cpp ${PROJECT_SOURCE_DIR}/utils.cpp)
+target_link_libraries(supernet nvinfer)
+target_link_libraries(supernet cudart)
+target_link_libraries(supernet ${OpenCV_LIBS})
+
+add_definitions(-O2 -pthread)
\ No newline at end of file
diff --git a/superpoint/README.md b/superpoint/README.md
new file mode 100644
index 0000000..f4b9b6b
--- /dev/null
+++ b/superpoint/README.md
@@ -0,0 +1,67 @@
+# SuperPoint
+
+The PyTorch implementation is from [magicleap/SuperPointPretrainedNetwork.](https://github.com/magicleap/SuperPointPretrainedNetwork)
+
+The pretrained models are from [magicleap/SuperPointPretrainedNetwork.](https://github.com/magicleap/SuperPointPretrainedNetwork)
+
+
+## Config
+
+- FP16/FP32 can be selected by the macro `USE_FP16` in supernet.cpp
+- GPU id and batch size can be selected by the macro `DEVICE` & `BATCH_SIZE` in supernet.cpp
+
+
+## How to Run
+1.Generate .wts file from the baseline pytorch implementation of pretrained model. The following example described how to generate superpoint_v1.wts from pytorch implementation of superpoint_v1.
+```
+git clone https://github.com/xiang-wuu/SuperPointPretrainedNetwork
+cd SuperPointPretrainedNetwork
+git checkout deploy
+// copy tensorrtx/superpoint/gen_wts.py to here(SuperPointPretrainedNetwork)
+python gen_wts.py
+// a file 'superpoint_v1.wts' will be generated.
+// before running gen_wts.py python script make sure you cloned private fork and checkout to deploy branch.
+```
+
+2.Put .wts file into tensorrtx/superpoint, build and run
+```
+cd tensorrtx/superpoint
+mkdir build
+cd build
+cmake ..
+make
+./supernet -s SuperPointPretrainedNetwork/superpoint_v1.wts // serialize model to plan file i.e. 'supernet.engine'
+```
+
+## Run Demo using SuperPointPretrainedNetwork Python Script
+The live demo can be run by inffering TensorRT generated engine file or by the pre-trained pytorch weight file , the `demo_superpoint.py` script is modified to infer automatically by either using TensorRT or PyTorch based on the provided input weight file.
+```
+cd SuperPointPretrainedNetwork
+python demo_superpoint.py assets/nyu_snippet.mp4 --cuda --weights_path tensorrtx/superpoint/build/supernet.engine
+// provide absolute path to supernet.engine as input weight file
+python demo_superpoint.py assets/nyu_snippet.mp4 --cuda --weights_path superpoint_v1.pth
+// execute above command to infer using pytorch pre-trained weight files instead of tensorrt engine file.
+```
+
+## Output
+As from the below result there is no significant difference in the inferred output!
+
+|
+PyTorch
+ |
+
+TensorRT
+ |
+
+
+
+ |
+
+
+ |
+
+
+
+## TODO
+- [ ] Optimizing post-processing using custom TensorRT layer.
+- [ ] Benchmark validation for speed accuracy tradeoff with [hpatches](https://github.com/hpatches/hpatches-benchmark) dataset
diff --git a/superpoint/gen_wts.py b/superpoint/gen_wts.py
new file mode 100644
index 0000000..23643d3
--- /dev/null
+++ b/superpoint/gen_wts.py
@@ -0,0 +1,20 @@
+import torch
+import struct
+from model import SuperPointNet
+
+model_name = "superpoint_v1"
+
+net = SuperPointNet()
+net.load_state_dict(torch.load("superpoint_v1.pth"))
+net = net.cuda()
+net.eval()
+
+f = open(model_name + ".wts", "w")
+f.write("{}\n".format(len(net.state_dict().keys())))
+for k, v in net.state_dict().items():
+ vr = v.reshape(-1).cpu().numpy()
+ f.write("{} {}".format(k, len(vr)))
+ for vv in vr:
+ f.write(" ")
+ f.write(struct.pack(">f", float(vv)).hex())
+ f.write("\n")
\ No newline at end of file
diff --git a/superpoint/logging.h b/superpoint/logging.h
new file mode 100644
index 0000000..fa8f3ca
--- /dev/null
+++ b/superpoint/logging.h
@@ -0,0 +1,517 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TENSORRT_LOGGING_H
+#define TENSORRT_LOGGING_H
+
+#include "NvInferRuntimeCommon.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using Severity = nvinfer1::ILogger::Severity;
+
+class LogStreamConsumerBuffer : public std::stringbuf
+{
+public:
+ LogStreamConsumerBuffer(std::ostream &stream, const std::string &prefix, bool shouldLog)
+ : mOutput(stream), mPrefix(prefix), mShouldLog(shouldLog)
+ {
+ }
+
+ LogStreamConsumerBuffer(LogStreamConsumerBuffer &&other)
+ : mOutput(other.mOutput)
+ {
+ }
+
+ ~LogStreamConsumerBuffer()
+ {
+ // std::streambuf::pbase() gives a pointer to the beginning of the buffered part of the output sequence
+ // std::streambuf::pptr() gives a pointer to the current position of the output sequence
+ // if the pointer to the beginning is not equal to the pointer to the current position,
+ // call putOutput() to log the output to the stream
+ if (pbase() != pptr())
+ {
+ putOutput();
+ }
+ }
+
+ // synchronizes the stream buffer and returns 0 on success
+ // synchronizing the stream buffer consists of inserting the buffer contents into the stream,
+ // resetting the buffer and flushing the stream
+ virtual int sync()
+ {
+ putOutput();
+ return 0;
+ }
+
+ void putOutput()
+ {
+ if (mShouldLog)
+ {
+ // prepend timestamp
+ std::time_t timestamp = std::time(nullptr);
+ tm *tm_local = std::localtime(×tamp);
+ std::cout << "[";
+ std::cout << std::setw(2) << std::setfill('0') << 1 + tm_local->tm_mon << "/";
+ std::cout << std::setw(2) << std::setfill('0') << tm_local->tm_mday << "/";
+ std::cout << std::setw(4) << std::setfill('0') << 1900 + tm_local->tm_year << "-";
+ std::cout << std::setw(2) << std::setfill('0') << tm_local->tm_hour << ":";
+ std::cout << std::setw(2) << std::setfill('0') << tm_local->tm_min << ":";
+ std::cout << std::setw(2) << std::setfill('0') << tm_local->tm_sec << "] ";
+ // std::stringbuf::str() gets the string contents of the buffer
+ // insert the buffer contents pre-appended by the appropriate prefix into the stream
+ mOutput << mPrefix << str();
+ // set the buffer to empty
+ str("");
+ // flush the stream
+ mOutput.flush();
+ }
+ }
+
+ void setShouldLog(bool shouldLog)
+ {
+ mShouldLog = shouldLog;
+ }
+
+private:
+ std::ostream &mOutput;
+ std::string mPrefix;
+ bool mShouldLog;
+};
+
+//!
+//! \class LogStreamConsumerBase
+//! \brief Convenience object used to initialize LogStreamConsumerBuffer before std::ostream in LogStreamConsumer
+//!
+class LogStreamConsumerBase
+{
+public:
+ LogStreamConsumerBase(std::ostream &stream, const std::string &prefix, bool shouldLog)
+ : mBuffer(stream, prefix, shouldLog)
+ {
+ }
+
+protected:
+ LogStreamConsumerBuffer mBuffer;
+};
+
+//!
+//! \class LogStreamConsumer
+//! \brief Convenience object used to facilitate use of C++ stream syntax when logging messages.
+//! Order of base classes is LogStreamConsumerBase and then std::ostream.
+//! This is because the LogStreamConsumerBase class is used to initialize the LogStreamConsumerBuffer member field
+//! in LogStreamConsumer and then the address of the buffer is passed to std::ostream.
+//! This is necessary to prevent the address of an uninitialized buffer from being passed to std::ostream.
+//! Please do not change the order of the parent classes.
+//!
+class LogStreamConsumer : protected LogStreamConsumerBase, public std::ostream
+{
+public:
+ //! \brief Creates a LogStreamConsumer which logs messages with level severity.
+ //! Reportable severity determines if the messages are severe enough to be logged.
+ LogStreamConsumer(Severity reportableSeverity, Severity severity)
+ : LogStreamConsumerBase(severityOstream(severity), severityPrefix(severity), severity <= reportableSeverity), std::ostream(&mBuffer) // links the stream buffer with the stream
+ ,
+ mShouldLog(severity <= reportableSeverity), mSeverity(severity)
+ {
+ }
+
+ LogStreamConsumer(LogStreamConsumer &&other)
+ : LogStreamConsumerBase(severityOstream(other.mSeverity), severityPrefix(other.mSeverity), other.mShouldLog), std::ostream(&mBuffer) // links the stream buffer with the stream
+ ,
+ mShouldLog(other.mShouldLog), mSeverity(other.mSeverity)
+ {
+ }
+
+ void setReportableSeverity(Severity reportableSeverity)
+ {
+ mShouldLog = mSeverity <= reportableSeverity;
+ mBuffer.setShouldLog(mShouldLog);
+ }
+
+private:
+ static std::ostream &severityOstream(Severity severity)
+ {
+ return severity >= Severity::kINFO ? std::cout : std::cerr;
+ }
+
+ static std::string severityPrefix(Severity severity)
+ {
+ switch (severity)
+ {
+ case Severity::kINTERNAL_ERROR:
+ return "[F] ";
+ case Severity::kERROR:
+ return "[E] ";
+ case Severity::kWARNING:
+ return "[W] ";
+ case Severity::kINFO:
+ return "[I] ";
+ case Severity::kVERBOSE:
+ return "[V] ";
+ default:
+ assert(0);
+ return "";
+ }
+ }
+
+ bool mShouldLog;
+ Severity mSeverity;
+};
+
+//! \class Logger
+//!
+//! \brief Class which manages logging of TensorRT tools and samples
+//!
+//! \details This class provides a common interface for TensorRT tools and samples to log information to the console,
+//! and supports logging two types of messages:
+//!
+//! - Debugging messages with an associated severity (info, warning, error, or internal error/fatal)
+//! - Test pass/fail messages
+//!
+//! The advantage of having all samples use this class for logging as opposed to emitting directly to stdout/stderr is
+//! that the logic for controlling the verbosity and formatting of sample output is centralized in one location.
+//!
+//! In the future, this class could be extended to support dumping test results to a file in some standard format
+//! (for example, JUnit XML), and providing additional metadata (e.g. timing the duration of a test run).
+//!
+//! TODO: For backwards compatibility with existing samples, this class inherits directly from the nvinfer1::ILogger
+//! interface, which is problematic since there isn't a clean separation between messages coming from the TensorRT
+//! library and messages coming from the sample.
+//!
+//! In the future (once all samples are updated to use Logger::getTRTLogger() to access the ILogger) we can refactor the
+//! class to eliminate the inheritance and instead make the nvinfer1::ILogger implementation a member of the Logger
+//! object.
+
+class Logger : public nvinfer1::ILogger
+{
+public:
+ Logger(Severity severity = Severity::kWARNING)
+ : mReportableSeverity(severity)
+ {
+ }
+
+ //!
+ //! \enum TestResult
+ //! \brief Represents the state of a given test
+ //!
+ enum class TestResult
+ {
+ kRUNNING, //!< The test is running
+ kPASSED, //!< The test passed
+ kFAILED, //!< The test failed
+ kWAIVED //!< The test was waived
+ };
+
+ //!
+ //! \brief Forward-compatible method for retrieving the nvinfer::ILogger associated with this Logger
+ //! \return The nvinfer1::ILogger associated with this Logger
+ //!
+ //! TODO Once all samples are updated to use this method to register the logger with TensorRT,
+ //! we can eliminate the inheritance of Logger from ILogger
+ //!
+ nvinfer1::ILogger &getTRTLogger()
+ {
+ return *this;
+ }
+
+ //!
+ //! \brief Implementation of the nvinfer1::ILogger::log() virtual method
+ //!
+ //! Note samples should not be calling this function directly; it will eventually go away once we eliminate the
+ //! inheritance from nvinfer1::ILogger
+ //!
+ void log(Severity severity, const char *msg) noexcept override
+ {
+ LogStreamConsumer(mReportableSeverity, severity) << "[TRT] " << std::string(msg) << std::endl;
+ }
+
+ //!
+ //! \brief Method for controlling the verbosity of logging output
+ //!
+ //! \param severity The logger will only emit messages that have severity of this level or higher.
+ //!
+ void setReportableSeverity(Severity severity)
+ {
+ mReportableSeverity = severity;
+ }
+
+ //!
+ //! \brief Opaque handle that holds logging information for a particular test
+ //!
+ //! This object is an opaque handle to information used by the Logger to print test results.
+ //! The sample must call Logger::defineTest() in order to obtain a TestAtom that can be used
+ //! with Logger::reportTest{Start,End}().
+ //!
+ class TestAtom
+ {
+ public:
+ TestAtom(TestAtom &&) = default;
+
+ private:
+ friend class Logger;
+
+ TestAtom(bool started, const std::string &name, const std::string &cmdline)
+ : mStarted(started), mName(name), mCmdline(cmdline)
+ {
+ }
+
+ bool mStarted;
+ std::string mName;
+ std::string mCmdline;
+ };
+
+ //!
+ //! \brief Define a test for logging
+ //!
+ //! \param[in] name The name of the test. This should be a string starting with
+ //! "TensorRT" and containing dot-separated strings containing
+ //! the characters [A-Za-z0-9_].
+ //! For example, "TensorRT.sample_googlenet"
+ //! \param[in] cmdline The command line used to reproduce the test
+ //
+ //! \return a TestAtom that can be used in Logger::reportTest{Start,End}().
+ //!
+ static TestAtom defineTest(const std::string &name, const std::string &cmdline)
+ {
+ return TestAtom(false, name, cmdline);
+ }
+
+ //!
+ //! \brief A convenience overloaded version of defineTest() that accepts an array of command-line arguments
+ //! as input
+ //!
+ //! \param[in] name The name of the test
+ //! \param[in] argc The number of command-line arguments
+ //! \param[in] argv The array of command-line arguments (given as C strings)
+ //!
+ //! \return a TestAtom that can be used in Logger::reportTest{Start,End}().
+ static TestAtom defineTest(const std::string &name, int argc, char const *const *argv)
+ {
+ auto cmdline = genCmdlineString(argc, argv);
+ return defineTest(name, cmdline);
+ }
+
+ //!
+ //! \brief Report that a test has started.
+ //!
+ //! \pre reportTestStart() has not been called yet for the given testAtom
+ //!
+ //! \param[in] testAtom The handle to the test that has started
+ //!
+ static void reportTestStart(TestAtom &testAtom)
+ {
+ reportTestResult(testAtom, TestResult::kRUNNING);
+ assert(!testAtom.mStarted);
+ testAtom.mStarted = true;
+ }
+
+ //!
+ //! \brief Report that a test has ended.
+ //!
+ //! \pre reportTestStart() has been called for the given testAtom
+ //!
+ //! \param[in] testAtom The handle to the test that has ended
+ //! \param[in] result The result of the test. Should be one of TestResult::kPASSED,
+ //! TestResult::kFAILED, TestResult::kWAIVED
+ //!
+ static void reportTestEnd(const TestAtom &testAtom, TestResult result)
+ {
+ assert(result != TestResult::kRUNNING);
+ assert(testAtom.mStarted);
+ reportTestResult(testAtom, result);
+ }
+
+ static int reportPass(const TestAtom &testAtom)
+ {
+ reportTestEnd(testAtom, TestResult::kPASSED);
+ return EXIT_SUCCESS;
+ }
+
+ static int reportFail(const TestAtom &testAtom)
+ {
+ reportTestEnd(testAtom, TestResult::kFAILED);
+ return EXIT_FAILURE;
+ }
+
+ static int reportWaive(const TestAtom &testAtom)
+ {
+ reportTestEnd(testAtom, TestResult::kWAIVED);
+ return EXIT_SUCCESS;
+ }
+
+ static int reportTest(const TestAtom &testAtom, bool pass)
+ {
+ return pass ? reportPass(testAtom) : reportFail(testAtom);
+ }
+
+ Severity getReportableSeverity() const
+ {
+ return mReportableSeverity;
+ }
+
+private:
+ //!
+ //! \brief returns an appropriate string for prefixing a log message with the given severity
+ //!
+ static const char *severityPrefix(Severity severity)
+ {
+ switch (severity)
+ {
+ case Severity::kINTERNAL_ERROR:
+ return "[F] ";
+ case Severity::kERROR:
+ return "[E] ";
+ case Severity::kWARNING:
+ return "[W] ";
+ case Severity::kINFO:
+ return "[I] ";
+ case Severity::kVERBOSE:
+ return "[V] ";
+ default:
+ assert(0);
+ return "";
+ }
+ }
+
+ //!
+ //! \brief returns an appropriate string for prefixing a test result message with the given result
+ //!
+ static const char *testResultString(TestResult result)
+ {
+ switch (result)
+ {
+ case TestResult::kRUNNING:
+ return "RUNNING";
+ case TestResult::kPASSED:
+ return "PASSED";
+ case TestResult::kFAILED:
+ return "FAILED";
+ case TestResult::kWAIVED:
+ return "WAIVED";
+ default:
+ assert(0);
+ return "";
+ }
+ }
+
+ //!
+ //! \brief returns an appropriate output stream (cout or cerr) to use with the given severity
+ //!
+ static std::ostream &severityOstream(Severity severity)
+ {
+ return severity >= Severity::kINFO ? std::cout : std::cerr;
+ }
+
+ //!
+ //! \brief method that implements logging test results
+ //!
+ static void reportTestResult(const TestAtom &testAtom, TestResult result)
+ {
+ severityOstream(Severity::kINFO) << "&&&& " << testResultString(result) << " " << testAtom.mName << " # "
+ << testAtom.mCmdline << std::endl;
+ }
+
+ //!
+ //! \brief generate a command line string from the given (argc, argv) values
+ //!
+ static std::string genCmdlineString(int argc, char const *const *argv)
+ {
+ std::stringstream ss;
+ for (int i = 0; i < argc; i++)
+ {
+ if (i > 0)
+ ss << " ";
+ ss << argv[i];
+ }
+ return ss.str();
+ }
+
+ Severity mReportableSeverity;
+};
+
+namespace
+{
+
+ //!
+ //! \brief produces a LogStreamConsumer object that can be used to log messages of severity kVERBOSE
+ //!
+ //! Example usage:
+ //!
+ //! LOG_VERBOSE(logger) << "hello world" << std::endl;
+ //!
+ inline LogStreamConsumer LOG_VERBOSE(const Logger &logger)
+ {
+ return LogStreamConsumer(logger.getReportableSeverity(), Severity::kVERBOSE);
+ }
+
+ //!
+ //! \brief produces a LogStreamConsumer object that can be used to log messages of severity kINFO
+ //!
+ //! Example usage:
+ //!
+ //! LOG_INFO(logger) << "hello world" << std::endl;
+ //!
+ inline LogStreamConsumer LOG_INFO(const Logger &logger)
+ {
+ return LogStreamConsumer(logger.getReportableSeverity(), Severity::kINFO);
+ }
+
+ //!
+ //! \brief produces a LogStreamConsumer object that can be used to log messages of severity kWARNING
+ //!
+ //! Example usage:
+ //!
+ //! LOG_WARN(logger) << "hello world" << std::endl;
+ //!
+ inline LogStreamConsumer LOG_WARN(const Logger &logger)
+ {
+ return LogStreamConsumer(logger.getReportableSeverity(), Severity::kWARNING);
+ }
+
+ //!
+ //! \brief produces a LogStreamConsumer object that can be used to log messages of severity kERROR
+ //!
+ //! Example usage:
+ //!
+ //! LOG_ERROR(logger) << "hello world" << std::endl;
+ //!
+ inline LogStreamConsumer LOG_ERROR(const Logger &logger)
+ {
+ return LogStreamConsumer(logger.getReportableSeverity(), Severity::kERROR);
+ }
+
+ //!
+ //! \brief produces a LogStreamConsumer object that can be used to log messages of severity kINTERNAL_ERROR
+ // ("fatal" severity)
+ //!
+ //! Example usage:
+ //!
+ //! LOG_FATAL(logger) << "hello world" << std::endl;
+ //!
+ inline LogStreamConsumer LOG_FATAL(const Logger &logger)
+ {
+ return LogStreamConsumer(logger.getReportableSeverity(), Severity::kINTERNAL_ERROR);
+ }
+
+} // anonymous namespace
+
+#endif // TENSORRT_LOGGING_H
diff --git a/superpoint/supernet.cpp b/superpoint/supernet.cpp
new file mode 100644
index 0000000..0dfd202
--- /dev/null
+++ b/superpoint/supernet.cpp
@@ -0,0 +1,209 @@
+#include
+#include
+#include