Skip to content
Open
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,5 @@ python/mage/link_prediction/random_customer_results.txt
python/mage/link_prediction/cora_results.txt
python/mage/link_prediction/random_features_services_results.txt
python/mage/link_prediction/issue.py
python/mage/link_prediction/issue2.py
python/mage/link_prediction/issue2.py.build-staging/
rebuild-cugraph.sh
155 changes: 63 additions & 92 deletions Dockerfile.cugraph
Original file line number Diff line number Diff line change
@@ -1,133 +1,104 @@
ARG CUGRAPH_VERSION=22.02
ARG CUDA_VERSION=11.5
ARG CUDA_VERSION_MINOR=11.5.2
ARG PY_VERSION=3.8
ARG RAPIDS_VERSION=25.12
ARG CUDA_VERSION=13
ARG CUDA_VERSION_MINOR=13.1.0
ARG PY_VERSION=3.12
ARG MG_VERSION=3.7.2

FROM rapidsai/rapidsai:${CUGRAPH_VERSION}-cuda${CUDA_VERSION}-runtime-ubuntu20.04-py${PY_VERSION} as cugraph-dev
FROM nvcr.io/nvidia/rapidsai/base:${RAPIDS_VERSION}-cuda${CUDA_VERSION}-py${PY_VERSION} AS cugraph-dev

FROM nvidia/cuda:${CUDA_VERSION_MINOR}-devel-ubuntu20.04 AS dev
FROM nvidia/cuda:${CUDA_VERSION_MINOR}-devel-ubuntu24.04 AS dev

USER root

ARG DEBIAN_FRONTEND=noninteractive
ARG MG_VERSION
ARG PY_VERSION
ENV MG_VERSION ${MG_VERSION}
ENV PY_VERSION ${PY_VERSION}
ENV MG_VERSION=${MG_VERSION}
ENV PY_VERSION=${PY_VERSION}

# Copy RAPIDS libraries
COPY --from=cugraph-dev /opt/conda/envs/rapids/lib/libcugraph.so /opt/conda/envs/rapids/lib/libcugraph.so
COPY --from=cugraph-dev /opt/conda/envs/rapids/include /opt/conda/envs/rapids/include
COPY --from=cugraph-dev /opt/conda/lib/libcugraph.so /opt/conda/lib/libcugraph.so
COPY --from=cugraph-dev /opt/conda/lib/libcugraph_c.so /opt/conda/lib/libcugraph_c.so
COPY --from=cugraph-dev /opt/conda/lib/librmm.so /opt/conda/lib/librmm.so
COPY --from=cugraph-dev /opt/conda/lib/librapids_logger.so /opt/conda/lib/librapids_logger.so
COPY --from=cugraph-dev /opt/conda/include /opt/conda/include

# Prevent from linking the Conda environment
ENV LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/local/cuda/lib64:/usr/local/lib
ENV LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/local/cuda/lib64:/usr/local/lib:/opt/conda/lib

# NVIDIA key rotation
RUN rm /etc/apt/sources.list.d/cuda.list

# Essentials for production/dev
RUN apt-get update && apt-get install -y \
libcurl4 `memgraph` \
libpython${PY_VERSION} `memgraph` \
libssl-dev `memgraph` \
libssl-dev `memgraph` \
openssl `memgraph` \
build-essential `mage-memgraph` \
curl `mage-memgraph` \
g++ `mage-memgraph` \
python3 `mage-memgraph` \
python3-pip `mage-memgraph` \
python3-setuptools `mage-memgraph` \
python3-dev `mage-memgraph` \
clang `mage-memgraph` \
git `mage-memgraph` \
software-properties-common `mage-cugraph` \
lsb-release `mage-cugraph` \
wget `mage-cugraph` \
uuid-dev \
gdb \
procps \
linux-perf \
libc6-dbg \
--no-install-recommends && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \
# Install newest CMake (cuGraph requires >= 20.01)
wget -qO - https://apt.kitware.com/keys/kitware-archive-latest.asc | apt-key add - && \
apt-add-repository "deb https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" && \
apt-get install -y \
cmake `mage-memgraph` \
--no-install-recommends

ENV PATH=/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/cmake:/usr/lib/cmake

# Memgraph listens for Bolt Protocol on this port by default.
libcurl4t64 libpython${PY_VERSION} libssl-dev openssl build-essential curl g++ \
python3 python3-pip python3-setuptools python3-dev clang git \
software-properties-common lsb-release wget uuid-dev gdb procps \
linux-tools-generic ninja-build libc6-dbg cmake libboost-all-dev \
unixodbc-dev --no-install-recommends && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

ENV PATH=/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

EXPOSE 7687

# Copy and build MAGE
RUN curl https://download.memgraph.com/memgraph/v${MG_VERSION}/ubuntu-24.04/memgraph_${MG_VERSION}-1_amd64.deb --output memgraph.deb \
&& dpkg -i memgraph.deb && rm memgraph.deb

WORKDIR /mage

# Copy local source (includes updated cuGraph files for RAPIDS 25.x)
COPY . /mage

ENV CXXFLAGS="-DLIBCUDACXX_ENABLE_EXPERIMENTAL_MEMORY_RESOURCE"
ENV CUDAFLAGS="-DLIBCUDACXX_ENABLE_EXPERIMENTAL_MEMORY_RESOURCE"

# Install PyTorch with CUDA 13.0 support FIRST
# Then install all dependencies that require matching PyTorch/CUDA versions
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y && \
export PATH="/root/.cargo/bin:${PATH}" && \
python3 -m pip install -r /mage/python/requirements.txt && \
python3 -m pip install -r /mage/python/tests/requirements.txt && \
python3 -m pip install dgl -f https://data.dgl.ai/wheels/repo.html && \
python3 /mage/setup build \
--gpu \
--cpp-build-flags MAGE_CUGRAPH_ROOT=/opt/conda/envs/rapids/ CMAKE_BUILD_TYPE=Release \
-p /usr/lib/memgraph/query_modules/

#DGL build from source
RUN git clone --recurse-submodules -b 0.9.x https://github.com/dmlc/dgl.git \
&& cd dgl && mkdir build && cd build && cmake -DUSE_CUDA=ON .. \
&& make -j4 && cd ../python && python3 setup.py install
export PATH="/root/.cargo/bin:${PATH}" && \
python3 -m pip install --break-system-packages torch torchvision --index-url https://download.pytorch.org/whl/cu130 && \
python3 -m pip install --break-system-packages --ignore-installed -r /mage/python/requirements.txt && \
python3 -m pip install --break-system-packages --ignore-installed -r /mage/python/tests/requirements.txt && \
python3 -m pip install --break-system-packages dgl -f https://data.dgl.ai/wheels/torch-2.9/cu130/repo.html && \
python3 -m pip install --break-system-packages torch_geometric && \
python3 -m pip install --break-system-packages ninja wheel && \
python3 -m pip install --break-system-packages --no-build-isolation git+https://github.com/pyg-team/pyg-lib.git && \
python3 -m pip install --break-system-packages --no-build-isolation git+https://github.com/rusty1s/pytorch_scatter.git && \
python3 -m pip install --break-system-packages --no-build-isolation git+https://github.com/rusty1s/pytorch_sparse.git && \
python3 -m pip install --break-system-packages --no-build-isolation git+https://github.com/rusty1s/pytorch_cluster.git && \
python3 -m pip install --break-system-packages --no-build-isolation git+https://github.com/rusty1s/pytorch_spline_conv.git && \
python3 -m pip install --break-system-packages --upgrade numpy gensim && \
python3 /mage/setup build --gpu \
--cpp-build-flags MAGE_CUGRAPH_ROOT=/opt/conda/ CMAKE_BUILD_TYPE=Release \
-p /usr/lib/memgraph/query_modules/

USER memgraph
ENTRYPOINT ["/usr/lib/memgraph/memgraph"]

FROM nvidia/cuda:${CUDA_VERSION_MINOR}-runtime-ubuntu20.04 AS prod
FROM nvidia/cuda:${CUDA_VERSION_MINOR}-runtime-ubuntu24.04 AS prod

USER root

ARG DEBIAN_FRONTEND=noninteractive
ARG MG_VERSION
ARG PY_VERSION
ENV MG_VERSION ${MG_VERSION}
ENV PY_VERSION ${PY_VERSION}
ENV MG_VERSION=${MG_VERSION}
ENV PY_VERSION=${PY_VERSION}

# Copy modules
COPY --from=dev /usr/lib/memgraph/query_modules/ /usr/lib/memgraph/query_modules/
# Copy cugraph library
COPY --from=dev /opt/conda/envs/rapids/lib/libcugraph.so /opt/conda/envs/rapids/lib/libcugraph.so
# Copy python build
COPY --from=dev /opt/conda/lib/libcugraph.so /opt/conda/lib/libcugraph.so
COPY --from=dev /opt/conda/lib/libcugraph_c.so /opt/conda/lib/libcugraph_c.so
COPY --from=dev /opt/conda/lib/librmm.so /opt/conda/lib/librmm.so
COPY --from=dev /opt/conda/lib/librapids_logger.so /opt/conda/lib/librapids_logger.so
COPY --from=dev /usr/local/lib/python${PY_VERSION}/ /usr/local/lib/python${PY_VERSION}/

# NVIDIA key rotation
RUN rm /etc/apt/sources.list.d/cuda.list
ENV LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/local/cuda/lib64:/usr/local/lib:/opt/conda/lib

# Download and install Memgraph
RUN apt-get update && apt-get install -y \
libcurl4 `memgraph` \
libpython${PY_VERSION} `memgraph` \
libssl1.1 `memgraph` \
libssl-dev `memgraph` \
openssl `memgraph` \
curl `mage-memgraph` \
libgomp1 `mage-memgraph` \
python3 `mage-memgraph` \
python3-setuptools `mage-memgraph` \
&& curl https://download.memgraph.com/memgraph/v${MG_VERSION}/ubuntu-20.04/memgraph_${MG_VERSION}-1_amd64.deb --output memgraph.deb \
&& dpkg -i memgraph.deb \
&& rm memgraph.deb \
libcurl4t64 libpython${PY_VERSION} libssl3t64 openssl curl libgomp1 libatomic1 python3 python3-setuptools \
unixodbc --no-install-recommends \
&& curl https://download.memgraph.com/memgraph/v${MG_VERSION}/ubuntu-24.04/memgraph_${MG_VERSION}-1_amd64.deb --output memgraph.deb \
&& dpkg -i memgraph.deb && rm memgraph.deb \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN export PATH="/usr/local/lib/python${PY_VERSION}:${PATH}"
ENV PATH="/usr/local/lib/python${PY_VERSION}:${PATH}"

RUN rm -rf /mage \
&& export PATH="/usr/local/lib/python${PY_VERSION}:${PATH}" \
&& apt-get -y --purge autoremove curl python3-dev \
&& apt-get clean
RUN rm -rf /mage && apt-get -y --purge autoremove curl python3-dev && apt-get clean

USER memgraph
ENTRYPOINT ["/usr/lib/memgraph/memgraph"]
34 changes: 25 additions & 9 deletions cpp/cugraph_module/algorithms/balanced_cut_clustering.cu
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2016-2022 Memgraph Ltd. [https://memgraph.com]
// Modified for cuGraph 25.x API compatibility - uses legacy CSR API
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -12,10 +13,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// NOTE: balancedCutClustering only exists in the legacy cugraph::ext_raft namespace
// and requires legacy::GraphCSRView. There is no modern API equivalent.

#include <cugraph/legacy/graph.hpp>
#include <cugraph/algorithms.hpp>

#include "mg_cugraph_utility.hpp"

namespace {
// TODO: Check Balanced Cut API. Update in new cuGraph API.
// NOTE: Spectral clustering legacy API only supports int32_t vertex/edge types
using vertex_t = int32_t;
using edge_t = int32_t;
using weight_t = double;
Expand Down Expand Up @@ -55,7 +62,6 @@ void InsertBalancedCutResult(mgp_graph *graph, mgp_result *result, mgp_memory *m

void BalancedCutClusteringProc(mgp_list *args, mgp_graph *graph, mgp_result *result, mgp_memory *memory) {
try {
// TODO: Not supporting int64_t
int num_clusters = mgp::value_get_int(mgp::list_at(args, 0));
int num_eigenvectors = mgp::value_get_int(mgp::list_at(args, 1));
double ev_tolerance = mgp::value_get_double(mgp::list_at(args, 2));
Expand All @@ -74,20 +80,30 @@ void BalancedCutClusteringProc(mgp_list *args, mgp_graph *graph, mgp_result *res
raft::handle_t handle{};
auto stream = handle.get_stream();

// IMPORTANT: Balanced cut cuGraph algorithm works only on legacy code
// IMPORTANT: Balanced cut cuGraph algorithm works only on legacy CSR graph format
auto cu_graph_ptr =
mg_cugraph::CreateCugraphLegacyFromMemgraph<vertex_t, edge_t, weight_t>(*mg_graph.get(), handle);
auto cu_graph_view = cu_graph_ptr->view();
cu_graph_view.prop.directed = false;

rmm::device_uvector<vertex_t> clustering_result(n_vertices, stream);
// Only supported for weighted graphs
cugraph::ext_raft::balancedCutClustering(cu_graph_view, num_clusters, num_eigenvectors, ev_tolerance, ev_maxiter,
kmean_tolerance, kmean_maxiter, clustering_result.data());

for (vertex_t node_id = 0; node_id < clustering_result.size(); ++node_id) {
auto cluster = clustering_result.element(node_id, stream);
InsertBalancedCutResult(graph, result, memory, mg_graph->GetMemgraphNodeId(node_id), cluster);
// Create RNG state for cuGraph 25.x API
raft::random::RngState rng_state(42);

// Call balancedCutClustering API - cuGraph 25.x requires handle and rng_state
cugraph::ext_raft::balancedCutClustering(handle, rng_state, cu_graph_view, num_clusters, num_eigenvectors,
static_cast<weight_t>(ev_tolerance), ev_maxiter,
static_cast<weight_t>(kmean_tolerance), kmean_maxiter,
clustering_result.data());

// Copy results to host and output
std::vector<vertex_t> h_clustering(n_vertices);
raft::update_host(h_clustering.data(), clustering_result.data(), n_vertices, stream);
handle.sync_stream();

for (vertex_t node_id = 0; node_id < static_cast<vertex_t>(n_vertices); ++node_id) {
InsertBalancedCutResult(graph, result, memory, mg_graph->GetMemgraphNodeId(node_id), h_clustering[node_id]);
}
} catch (const std::exception &e) {
// We must not let any exceptions out of our module.
Expand Down
Loading