Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions cpp/open3d/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ configure_file("${PROJECT_SOURCE_DIR}/cpp/open3d/Open3DConfig.h.in"

add_library(Open3D)

if (BUILD_PYTORCH_OPS)
target_compile_definitions(Open3D PUBLIC OPEN3D_BUILD_PYTORCH_OPS=1)
else()
target_compile_definitions(Open3D PUBLIC OPEN3D_BUILD_PYTORCH_OPS=0)
endif()

add_subdirectory(camera)
add_subdirectory(core)
add_subdirectory(data)
Expand Down
4 changes: 4 additions & 0 deletions cpp/open3d/ml/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@ if (BUILD_PYTORCH_OPS)
add_subdirectory(pytorch)
endif()

target_sources(Open3D PRIVATE
Model.cpp
)

add_subdirectory(contrib)
53 changes: 53 additions & 0 deletions cpp/open3d/ml/Model.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// ----------------------------------------------------------------------------
// - Open3D: www.open3d.org -
// ----------------------------------------------------------------------------
// Copyright (c) 2018-2024 www.open3d.org
// SPDX-License-Identifier: MIT
// ----------------------------------------------------------------------------

#include "open3d/ml/Model.h"

#include "open3d/utility/Logging.h"

namespace open3d {
namespace ml {

struct Model::Impl {
std::string artifact_path_;
bool loaded_ = false;
};

Model::Model() : impl_(std::make_unique<Impl>()) {}

Model::~Model() = default;

void Model::LoadModel(const std::string& artifact_path) {
// TODO: Implement dlopen of libtorch and AOTInductor runner loading.
// For now, just store the path and mark as loaded for testing purposes.
impl_->artifact_path_ = artifact_path;
impl_->loaded_ = true;
utility::LogInfo("Model::LoadModel called with path: {}", artifact_path);
}

std::vector<core::Tensor> Model::Forward(
const std::vector<core::Tensor>& inputs) const {
if (!impl_->loaded_) {
utility::LogError("Model not loaded. Call LoadModel() first.");
}
// TODO: Implement actual inference using AOTInductor runner.
// For now, return empty vector as placeholder.
utility::LogInfo("Model::Forward called with {} input tensors",
inputs.size());
return {};
}

bool IsPyTorchRuntimeEnabled() {
#if OPEN3D_BUILD_PYTORCH_OPS
return true;
#else
return false;
#endif
}

} // namespace ml
} // namespace open3d
44 changes: 44 additions & 0 deletions cpp/open3d/ml/Model.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// ----------------------------------------------------------------------------
// - Open3D: www.open3d.org -
// ----------------------------------------------------------------------------
// Copyright (c) 2018-2024 www.open3d.org
// SPDX-License-Identifier: MIT
// ----------------------------------------------------------------------------

#pragma once
#include <memory>
#include <string>
#include <vector>

#include "open3d/core/Tensor.h"

namespace open3d {
namespace ml {

/// \brief Minimal holder for lazily loaded torch models compiled through
/// AOTInductor. The class is intentionally lightweight so the API can stabilize
/// before the heavy runtime integration lands.
class Model {
public:
Model();
~Model();

/// Loads a compiled model artifact from disk. The concrete format is
/// expected to match the PyTorch AOTInductor runner output.
void LoadModel(const std::string& artifact_path);

/// Runs inference on the loaded model. Inputs are Open3D tensors so we can
/// take advantage of the existing DLPack bridges.
std::vector<core::Tensor> Forward(
const std::vector<core::Tensor>& inputs) const;

private:
struct Impl;
std::unique_ptr<Impl> impl_;
};

/// Returns true when Open3D was configured with BUILD_PYTORCH_OPS.
bool IsPyTorchRuntimeEnabled();

} // namespace ml
} // namespace open3d
1 change: 1 addition & 0 deletions cpp/tests/ml/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
target_sources(tests PRIVATE
Model.cpp
ShapeChecking.cpp
)
60 changes: 60 additions & 0 deletions cpp/tests/ml/Model.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// ----------------------------------------------------------------------------
// - Open3D: www.open3d.org -
// ----------------------------------------------------------------------------
// Copyright (c) 2018-2024 www.open3d.org
// SPDX-License-Identifier: MIT
// ----------------------------------------------------------------------------

#include "open3d/ml/Model.h"

#include "open3d/core/Tensor.h"
#include "tests/Tests.h"

namespace open3d {
namespace tests {

TEST(Model, Constructor) {
ml::Model model;
// Should construct without throwing
}

TEST(Model, IsPyTorchRuntimeEnabled) {
bool enabled = ml::IsPyTorchRuntimeEnabled();
#if OPEN3D_BUILD_PYTORCH_OPS
EXPECT_TRUE(enabled);
#else
EXPECT_FALSE(enabled);
#endif
}

TEST(Model, ForwardWithoutLoad) {
ml::Model model;
std::vector<core::Tensor> inputs;
// Forward without LoadModel should throw/log error
EXPECT_ANY_THROW(model.Forward(inputs));
}

TEST(Model, LoadModelAndForward) {
ml::Model model;
// LoadModel with dummy path (stub implementation just stores path)
EXPECT_NO_THROW(model.LoadModel("/tmp/dummy_model.pt"));
// Forward with empty inputs (stub returns empty vector)
std::vector<core::Tensor> inputs;
auto outputs = model.Forward(inputs);
EXPECT_TRUE(outputs.empty()); // Stub returns empty
}

TEST(Model, ForwardWithInputTensors) {
ml::Model model;
model.LoadModel("/tmp/dummy_model.pt");
// Create test input tensors
std::vector<core::Tensor> inputs;
inputs.push_back(core::Tensor::Ones({2, 3}, core::Float32));
inputs.push_back(core::Tensor::Zeros({4, 5}, core::Float32));
// Stub should accept inputs without crashing
auto outputs = model.Forward(inputs);
EXPECT_TRUE(outputs.empty()); // Stub returns empty
}

} // namespace tests
} // namespace open3d