From da5919cf84b6ef53819492b8edd6bad7b95e6a11 Mon Sep 17 00:00:00 2001 From: Dimitri Date: Sun, 26 Apr 2026 17:45:08 -0300 Subject: [PATCH 1/4] histogram --- Directory.Build.props | 4 ++ Directory.Build.targets | 3 +- pkg/pack.proj | 4 +- src/Native/LibTorchSharp/CMakeLists.txt | 13 ++++ src/Native/LibTorchSharp/THSHistogram.cpp | 63 +++++++++++++++++++ src/Native/LibTorchSharp/THSHistogram.h | 14 +++++ src/Native/build.proj | 7 ++- .../PInvoke/LibTorchSharp.THSHistogram.cs | 60 ++++++++++++++++++ .../Tensor/torch.OtherOperations.cs | 39 +++++++++--- src/TorchSharp/TorchSharp.csproj | 10 ++- test/Directory.Build.props | 2 +- .../TorchSharpTest.WithCudaBinaries.csproj | 1 + test/TorchSharpTest/TorchSharpTest.csproj | 1 + 13 files changed, 203 insertions(+), 18 deletions(-) create mode 100644 src/Native/LibTorchSharp/THSHistogram.cpp create mode 100644 src/Native/LibTorchSharp/THSHistogram.h create mode 100644 src/TorchSharp/PInvoke/LibTorchSharp.THSHistogram.cs diff --git a/Directory.Build.props b/Directory.Build.props index e8e44ee50..2fb85d34e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -5,6 +5,7 @@ + Debug Debug;Release <_DefaultArchitecture>$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLower()) @@ -167,6 +168,9 @@ $(DefineContants);DEBUG false + + $(DefineContants);CUDA_TOOLKIT_FOUND + true diff --git a/Directory.Build.targets b/Directory.Build.targets index 4ab3c814c..5c5de8686 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -84,6 +84,7 @@ + \ No newline at end of file diff --git a/pkg/pack.proj b/pkg/pack.proj index 3c9db2f98..45c2f75ec 100644 --- a/pkg/pack.proj +++ b/pkg/pack.proj @@ -1,6 +1,7 @@ - + + @@ -29,5 +30,4 @@ - diff --git a/src/Native/LibTorchSharp/CMakeLists.txt b/src/Native/LibTorchSharp/CMakeLists.txt index 60b61f049..e05cfda47 100644 --- a/src/Native/LibTorchSharp/CMakeLists.txt +++ b/src/Native/LibTorchSharp/CMakeLists.txt @@ -1,5 +1,12 @@ project(LibTorchSharp) +find_package(CUDA) +if(CUDA_FOUND) + include_directories(${CUDA_INCLUDE_DIRS}) + link_directories(${CUDA_LIBRARY_DIRS}) + add_compile_definitions(TORCHSHARP_CUDA_TOOLKIT_FOUND) +endif() + if(APPLE AND NOT LIBTORCH_ARCH STREQUAL "arm64") include_directories("/usr/local/include" "/usr/local/opt/llvm/include") link_directories("/usr/local/lib" "/usr/local/opt/llvm/lib") @@ -9,6 +16,7 @@ find_package(Torch REQUIRED PATHS ${LIBTORCH_PATH}) set(SOURCES cifar10.h crc32c.h + THSHistogram.h THSAutograd.h THSData.h THSJIT.h @@ -21,6 +29,7 @@ set(SOURCES cifar10.cpp crc32c.c THSActivation.cpp + THSHistogram.cpp THSAutograd.cpp THSData.cpp THSFFT.cpp @@ -70,6 +79,10 @@ include_directories(${TORCH_INCLUDE_DIRS}) add_library(LibTorchSharp SHARED ${SOURCES} ${RESOURCES}) +if(CUDA_FOUND) +target_link_libraries(LibTorchSharp ${CUDA_LIBRARIES}) +endif() + target_link_libraries(LibTorchSharp ${TORCH_LIBRARIES}) set_property(TARGET LibTorchSharp PROPERTY CXX_STANDARD 14) diff --git a/src/Native/LibTorchSharp/THSHistogram.cpp b/src/Native/LibTorchSharp/THSHistogram.cpp new file mode 100644 index 000000000..32fbf67e6 --- /dev/null +++ b/src/Native/LibTorchSharp/THSHistogram.cpp @@ -0,0 +1,63 @@ +// Copyright (c) .NET Foundation and Contributors. All Rights Reserved. See LICENSE in the project root for license information. +#include "THSHistogram.h" + +void THSHistogram_histogram(const Tensor input, const int64_t bins, const double* ranges, int64_t length, Tensor weight, bool density, Tensor hist, Tensor hist_bins) +{ + CATCH( + //const auto tup = torch::histogram(*input, bins, ranges == nullptr ? std::nullopt : at::ArrayRef(ranges, length), *weight, density); + const auto tup = torch::histogram(*input, bins, at::ArrayRef(ranges, length), *weight, density); + *hist = std::get<0>(tup); + *hist_bins = std::get<1>(tup); + ) +} + +void THSHistogram_histogram_tensor(const Tensor input, const Tensor bins, Tensor weight, bool density, Tensor hist, Tensor hist_bins) +{ + CATCH( + auto tup = torch::histogram(*input, *bins, *weight, density); + *hist = std::get<0>(tup); + *hist_bins = std::get<1>(tup); + ) +} + +void THSHistogram_histogramdd(const Tensor input, const int64_t* bins, int64_t length, const double* ranges, int64_t length_ranges, Tensor weight, bool density, Tensor hist, Tensor*(*allocator)(size_t length_loc)) +{ + CATCH( + auto tup = torch::histogramdd(*input, at::IntArrayRef(bins, length), at::ArrayRef(ranges, length_ranges), *weight, density); + *hist = std::get<0>(tup); + auto res = std::get<1>(tup); + const size_t sz = res.size(); + Tensor* result = allocator(sz); + for (size_t i = 0; i < sz; i++) + result[i] = new torch::Tensor(res[i]); + ) +} + + + +void THSHistogram_histogramdd_intbins(const Tensor input, int64_t bins, const double* ranges, int64_t length_ranges, Tensor weight, bool density, Tensor hist, Tensor* (*allocator)(size_t length_loc)) +{ + CATCH( + auto tup = torch::histogramdd(*input, bins, at::ArrayRef(ranges, length_ranges), *weight, density); + *hist = std::get<0>(tup); + auto res = std::get<1>(tup); + const size_t sz = res.size(); + Tensor * result = allocator(sz); + for (size_t i = 0; i < sz; i++) + result[i] = new torch::Tensor(res[i]); + ) +} + + +void THSHistogram_histogramdd_tensors(const Tensor input, Tensor* tensors, int64_t length, const double* ranges, int64_t length_ranges, Tensor weight, bool density, Tensor hist, Tensor* (*allocator)(size_t length_loc)) +{ + CATCH( + auto tup = torch::histogramdd(*input, toTensors((torch::Tensor**)tensors, length), at::ArrayRef(ranges, length_ranges), *weight, density); + *hist = std::get<0>(tup); + auto res = std::get<1>(tup); + const size_t sz = res.size(); + Tensor * result = allocator(sz); + for (size_t i = 0; i < sz; i++) + result[i] = new torch::Tensor(res[i]); + ) +} \ No newline at end of file diff --git a/src/Native/LibTorchSharp/THSHistogram.h b/src/Native/LibTorchSharp/THSHistogram.h new file mode 100644 index 000000000..b2d665356 --- /dev/null +++ b/src/Native/LibTorchSharp/THSHistogram.h @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors. All Rights Reserved. See LICENSE in the project root for license information. +#pragma once + +#include "../Stdafx.h" + +#include "torch/torch.h" + +#include "Utils.h" + +EXPORT_API(void) THSHistogram_histogram(const Tensor input, const int64_t bins, const double* ranges, int64_t length, Tensor weight, bool density, Tensor hist, Tensor hist_bins); +EXPORT_API(void) THSHistogram_histogram_tensor(const Tensor input, const Tensor bins, Tensor weight, bool density, Tensor hist, Tensor hist_bins); +EXPORT_API(void) THSHistogram_histogramdd(const Tensor input, const int64_t* bins, int64_t length, const double* ranges, int64_t length_ranges, Tensor weight, bool density, Tensor hist, Tensor* (*allocator)(size_t length_loc)); +EXPORT_API(void) THSHistogram_histogramdd_intbins(const Tensor input, int64_t bins, const double* ranges, int64_t length_ranges, Tensor weight, bool density, Tensor hist, Tensor* (*allocator)(size_t length_loc)); +EXPORT_API(void) THSHistogram_histogramdd_tensors(const Tensor input, Tensor* tensors, int64_t length, const double* ranges, int64_t length_ranges, Tensor weight, bool density, Tensor hist, Tensor* (*allocator)(size_t length_loc)); \ No newline at end of file diff --git a/src/Native/build.proj b/src/Native/build.proj index 6dbbc70a9..c741b14f6 100644 --- a/src/Native/build.proj +++ b/src/Native/build.proj @@ -44,10 +44,13 @@ - + $(NativeConfiguration) $(TargetArchitecture) --libtorchpath $(LibTorchCmakePath) - + + + $(NativeConfiguration) $(TargetArchitecture) --libtorchpath $(CustomLibTorchFullPath) + diff --git a/src/TorchSharp/PInvoke/LibTorchSharp.THSHistogram.cs b/src/TorchSharp/PInvoke/LibTorchSharp.THSHistogram.cs new file mode 100644 index 000000000..c099cd2df --- /dev/null +++ b/src/TorchSharp/PInvoke/LibTorchSharp.THSHistogram.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace TorchSharp.PInvoke +{ + internal static partial class NativeMethods + { + [DllImport("LibTorchSharp")] + internal static extern void THSHistogram_histogram( + IntPtr input, + long bins, + IntPtr ranges, + long length, + IntPtr weight, + [MarshalAs(UnmanagedType.U1)]bool density, + out IntPtr hist, + out IntPtr hist_bins + ); + internal static extern void THSHistogram_tensor( + IntPtr input, + IntPtr bins, + IntPtr weight, + [MarshalAs(UnmanagedType.U1)] bool density, + out IntPtr hist, + out IntPtr hist_bins); + internal static extern void THSHistogramdd( + IntPtr input, + IntPtr bins, + long length, + IntPtr ranges, + long length_ranges, + IntPtr weight, + [MarshalAs(UnmanagedType.U1)] bool density, + out IntPtr hist, + AllocatePinnedArray allocator); + internal static extern void THSHistogramdd_intbins( + IntPtr input, + long bins, + IntPtr ranges, + long length_ranges, + IntPtr weight, + [MarshalAs(UnmanagedType.U1)] bool density, + out IntPtr hist, + AllocatePinnedArray allocator); + internal static extern void THSHistogramdd_tensors( + IntPtr input, + IntPtr tensors, + long length, + IntPtr ranges, + long length_ranges, + IntPtr weight, + [MarshalAs(UnmanagedType.U1)] bool density, + IntPtr hist, + AllocatePinnedArray allocator); + } +} diff --git a/src/TorchSharp/Tensor/torch.OtherOperations.cs b/src/TorchSharp/Tensor/torch.OtherOperations.cs index b4b092c4f..eb040d4b9 100644 --- a/src/TorchSharp/Tensor/torch.OtherOperations.cs +++ b/src/TorchSharp/Tensor/torch.OtherOperations.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection.Metadata; using TorchSharp.PInvoke; using static TorchSharp.PInvoke.NativeMethods; @@ -437,33 +438,53 @@ public static Tensor einsum(string equation, params Tensor[] tensors) // https://pytorch.org/docs/stable/generated/torch.histogram [Obsolete("not implemented", true)] - static Tensor histogram( - Tensor input, + static Tensor histogram(Tensor input, long bins, (float min, float max)? range = null, Tensor? weight = null, bool density = false) - => throw new NotImplementedException(); + { + var weightsHandle = (weight is null ? IntPtr.Zero : weight.Handle); + + if (range.HasValue) { + float[] ranges = new float[] { range.Value.min, range.Value.max }; + + unsafe { + + fixed (float* pranges = ranges) { + THSHistogram_histogram(input.handle, bins, (IntPtr)pranges, ranges.Length, weightsHandle, density, out IntPtr hist, out IntPtr hist_bins); + return new Tensor(hist); + } + } + } else { + THSHistogram_histogram(input.handle, bins, IntPtr.Zero, 0, weightsHandle, density, + out IntPtr hist, out IntPtr hist_bins); + return new Tensor(hist); + } + } // https://pytorch.org/docs/stable/generated/torch.histogram [Obsolete("not implemented", true)] - static Tensor histogram( - Tensor input, + static Tensor histogram(Tensor input, long[] bins, (float min, float max)? range = null, Tensor? weight = null, bool density = false) - => throw new NotImplementedException(); + { + throw new NotImplementedException(); + } + // https://pytorch.org/docs/stable/generated/torch.histogram [Obsolete("not implemented", true)] - static Tensor histogram( - Tensor input, + static Tensor histogram(Tensor input, Tensor[] bins, (float min, float max)? range = null, Tensor? weight = null, bool density = false) - => throw new NotImplementedException(); + { + throw new NotImplementedException(); + } // https://pytorch.org/docs/stable/generated/torch.histogramdd [Obsolete("not implemented", true)] diff --git a/src/TorchSharp/TorchSharp.csproj b/src/TorchSharp/TorchSharp.csproj index 2d227e2c8..91639d228 100644 --- a/src/TorchSharp/TorchSharp.csproj +++ b/src/TorchSharp/TorchSharp.csproj @@ -1,4 +1,4 @@ - + @@ -11,6 +11,7 @@ false false $(DefineConstants);LIBTORCH_$(LibTorchPackageVersion.Replace('.', '_'));CUDA_$(CudaVersionDot.Replace('.', '_')) + @@ -61,7 +62,10 @@ - + + + + @@ -71,7 +75,7 @@ - + diff --git a/test/Directory.Build.props b/test/Directory.Build.props index de003c15a..72877ac85 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -6,7 +6,7 @@ $(TargetFrameworks);net48 false true - + + \ No newline at end of file diff --git a/src/Native/build.proj b/src/Native/build.proj index c741b14f6..1f67671a7 100644 --- a/src/Native/build.proj +++ b/src/Native/build.proj @@ -57,7 +57,7 @@ - + - - - + @@ -74,7 +72,9 @@ - + + + From 5d2727cb52067d1589bad360974ed07239ff8efb Mon Sep 17 00:00:00 2001 From: Dimitri Date: Wed, 29 Apr 2026 16:54:06 -0300 Subject: [PATCH 4/4] Update CMakeLists.txt Cuda Quiet --- src/Native/LibTorchSharp/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Native/LibTorchSharp/CMakeLists.txt b/src/Native/LibTorchSharp/CMakeLists.txt index 12fb719cd..22e05e89d 100644 --- a/src/Native/LibTorchSharp/CMakeLists.txt +++ b/src/Native/LibTorchSharp/CMakeLists.txt @@ -1,6 +1,6 @@ project(LibTorchSharp) -find_package(CUDA) +find_package(CUDA QUIET) if(CUDA_FOUND) include_directories(${CUDA_INCLUDE_DIRS}) link_directories(${CUDA_LIBRARY_DIRS})