Skip to content

Instantly share code, notes, and snippets.

@OlegJakushkin
Last active March 19, 2022 06:52
Show Gist options
  • Save OlegJakushkin/48f64d527339070cce5776031e11cd4f to your computer and use it in GitHub Desktop.
Save OlegJakushkin/48f64d527339070cce5776031e11cd4f to your computer and use it in GitHub Desktop.
// in include folder
//
// Created by user on 26.02.2022.
//
#ifndef TORCHPP_API_H
#define TORCHPP_API_H
#include <vector>
#include <string>
struct ssdResult {
// location_offset_tensor ... {Batch=1, 4, Num of default box=8732}
// 4 ... 0: delta center x, 1: delta center y, 2: delta width, 3: delta height
// 8732 ... (38^2)*4[ratios] + (19^2)*6[ratios] + (10^2)*6[ratios] + (5^2)*6[ratios] + (3^2)*4[ratios] + (1^2)*4[ratios]
std::vector<float> outCoordinates;
// class_confidence_tensor ... {Batch=1, 81, Num of default box=8732}
// 81 ... 0: background confidence, 1~80: class confidence
// 8732 ... (38^2)*4[ratios] + (19^2)*6[ratios] + (10^2)*6[ratios] + (5^2)*6[ratios] + (3^2)*4[ratios] + (1^2)*4[ratios]
std::vector<float> outClasses;
std::vector<long> outShapeCoordinates;
std::vector<long> outShapeClasses;
};
ssdResult runSsd(std::vector<float> input, std::vector<long> shape, std::string ssd_pt_path );
#endif //TORCHPP_API_H
cmake_minimum_required(VERSION 3.15)
project(torc_ssd_hpp)
set(CMAKE_CXX_STANDARD 14)
find_package(Torch REQUIRED)
add_library(torc_ssd_hpp SHARED main.cpp include/api.h)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
target_link_libraries(torc_ssd_hpp "${TORCH_LIBRARIES}")
set_property(TARGET torc_ssd_hpp PROPERTY CXX_STANDARD 14)
if (MSVC)
#Todo: Not tested
file(GLOB TORCH_DLLS "${TORCH_INSTALL_PREFIX}/lib/*.dll")
add_custom_command(TARGET example-app
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${TORCH_DLLS}
$<TARGET_FILE_DIR:example-app>)
endif (MSVC)
#include "include/api.h"
#include <iostream>
#include <vector>
#include <array>
#include <algorithm>
#include <torch/torch.h>
#include <torch/script.h>
torch::Tensor from_vec(std::vector<float> & data) {
return torch::from_blob(data.data(), {(long)data.size()});
}
template<class T>
torch::Tensor from_vec(std::vector<T> data) {
std::vector<float> floatVec(data.begin(), data.end());
return from_vec(floatVec);
}
torch::Tensor from_vec(std::vector<float> & data, std::vector<long> shape) {
return torch::from_blob(data.data(), shape);
}
//Example
// std::vector<long> shape = {1,3,300,300};
// auto input = std::vector<float>(3*300*300, 0);
ssdResult runSsd(std::vector<float> input, std::vector<long> shape, std::string ssd_pt_path ) {
auto device = c10::Device("cpu");
auto model_ = torch::jit::load(ssd_pt_path, device );
std::cout << model_.dump_to_str(false, false, false) << std::endl;
model_.eval();
std::vector<torch::jit::IValue> inputs;
auto start_inference = std::chrono::high_resolution_clock::now();
torch::Tensor tensor_inputs;
std::cout << tensor_inputs.dtype() << std::endl;
tensor_inputs = torch::from_blob(input.data(), shape);
inputs.clear();
tensor_inputs = tensor_inputs.to(device);
inputs.emplace_back(tensor_inputs);
std::cout << inputs.size() << std::endl;
auto output = model_.forward(inputs).toTuple()->elements(); // det_boxes, det_labels, det_scores
auto end_inference = std::chrono::high_resolution_clock::now();
auto duration_inference = std::chrono::duration_cast<std::chrono::milliseconds>(end_inference - start_inference);
std::cout << "Inference: " << duration_inference.count() << " [milliseconds] \n";
std::cout << output.size() << " 0:" << output[0].toTensor().sizes() << " 1:" << output[1].toTensor().sizes() << std::endl;
auto result = ssdResult();
auto outShapeSizes = output[0].toTensor().sizes().vec();
long outSize = std::accumulate(outShapeSizes.begin(), outShapeSizes.end(), 1,
[](long a, long b) {
return a*b;
});
result.outShapeCoordinates = outShapeSizes;
auto beginPtrCoordinates = (float * )output[0].toTensor().data_ptr();
std::vector<float> outVecCoordinates(beginPtrCoordinates, beginPtrCoordinates + outSize);
result.outCoordinates =outVecCoordinates;
auto outShapeClasses = output[1].toTensor().sizes().vec();
long outSizeClasses = std::accumulate(outShapeClasses.begin(), outShapeClasses.end(), 1,
[](long a, long b) {
return a*b;
});
result.outShapeClasses = outShapeClasses;
auto beginPtrClasses = (float * )output[0].toTensor().data_ptr();
std::vector<float> outVecClasses(beginPtrClasses, beginPtrCoordinates + outSizeClasses);
result.outClasses=outVecClasses;
long accumulatedValue = std::accumulate(outVecCoordinates.begin(), outVecCoordinates.end(), 0);
std::cout << outVecCoordinates.size() << " from size:" << outSize <<
std::endl <<" what is inside in a brief:" << accumulatedValue << std::endl;
return result;
}
@OlegJakushkin
Copy link
Author

#Model from https://raw.githubusercontent.com/hotsuyuki/SSD300_PyTorch_cpp_TRTorch/main/model/ssd300_torchscript_B1-C3-H300-W300_torch1-5-1_cuda10-2_gpu.pt
#Configure cmake with -DTorch_DIR=/home/user/Documents/torch/libtorch/share/cmake/Torch
#Run from working directory /home/user/CLionProjects/torchpp/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment