mirror of
https://github.com/tig-foundation/tig-monorepo.git
synced 2026-02-21 10:27:49 +08:00
Rework architecture so each challenge has separate runtime & docker.
Some checks are pending
Test Workspace / Test Workspace (push) Waiting to run
Some checks are pending
Test Workspace / Test Workspace (push) Waiting to run
This commit is contained in:
parent
7ebad69cf7
commit
89d86f9deb
@ -1,8 +1,13 @@
|
||||
ARG BASE_IMAGE=ubuntu:24.04
|
||||
ARG CHALLENGE
|
||||
|
||||
# Development environment stage
|
||||
FROM ${BASE_IMAGE}
|
||||
|
||||
ARG CHALLENGE
|
||||
ENV CHALLENGE=${CHALLENGE}
|
||||
RUN if [ -z "$CHALLENGE" ]; then echo "Error: '--build-arg CHALLENGE' must be set." && exit 1; fi
|
||||
|
||||
RUN ARCH=$(uname -m) && \
|
||||
if [ "$ARCH" != "aarch64" ] && [ "$ARCH" != "arm64" ] && [ "$ARCH" != "amd64" ] && [ "$ARCH" != "x86_64" ]; then \
|
||||
echo "Unsupported architecture: $ARCH. Must be 'aarch64', 'arm64', 'amd64', or 'x86_64'." && exit 1; \
|
||||
@ -26,9 +31,8 @@ RUN ARCH=$(uname -m) && \
|
||||
rustup component add rust-src && \
|
||||
rustup target add $RUST_TARGET && \
|
||||
RUST_LIBDIR=$(rustc --print target-libdir --target=$RUST_TARGET) && \
|
||||
ln -s $RUST_LIBDIR /usr/local/lib/rust && \
|
||||
echo "export LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}:/usr/local/lib/rust\"" >> /etc/bash.bashrc && \
|
||||
echo "export RUST_TARGET=\"${RUST_TARGET}\"" >> /etc/bash.bashrc
|
||||
ln -s $RUST_LIBDIR /usr/local/lib/rust
|
||||
ENV LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/usr/local/lib/rust"
|
||||
|
||||
RUN ARCH=$(uname -m) && \
|
||||
LLVM_URL=$(if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then \
|
||||
@ -42,25 +46,20 @@ RUN ARCH=$(uname -m) && \
|
||||
rm -rf llvm.tar.zst && \
|
||||
ln -s /opt/llvm/bin/* /usr/local/bin/
|
||||
|
||||
COPY scripts/ /usr/local/bin/tig-scripts/
|
||||
COPY tig-binary/scripts/ /usr/local/bin/tig-scripts/
|
||||
RUN chmod +x /usr/local/bin/tig-scripts/*
|
||||
ENV PATH="/usr/local/bin/tig-scripts:${PATH}"
|
||||
|
||||
COPY . /tmp/tig-monorepo
|
||||
WORKDIR /tmp/tig-monorepo
|
||||
|
||||
RUN if command -v nvcc > /dev/null 2>&1; then \
|
||||
cargo build -r -p tig-runtime --features cuda && \
|
||||
cargo build -r -p tig-verifier --features cuda; \
|
||||
else \
|
||||
cargo build -r -p tig-runtime && \
|
||||
cargo build -r -p tig-verifier; \
|
||||
fi && \
|
||||
RUN cargo build -r -p tig-runtime --features $CHALLENGE && \
|
||||
cargo build -r -p tig-verifier --features $CHALLENGE && \
|
||||
mv target/release/tig-runtime /usr/local/bin/ && \
|
||||
mv target/release/tig-verifier /usr/local/bin/ && \
|
||||
chmod +x /usr/local/bin/tig-runtime && \
|
||||
chmod +x /usr/local/bin/tig-verifier && \
|
||||
rm -rf tig-monorepo
|
||||
|
||||
COPY scripts/ /usr/local/bin/tig-scripts/
|
||||
COPY tig-binary/scripts/ /usr/local/bin/tig-scripts/
|
||||
RUN chmod +x /usr/local/bin/tig-scripts/*
|
||||
ENV PATH="/usr/local/bin/tig-scripts:${PATH}"
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
@ -1,27 +1,28 @@
|
||||
ARG BASE_IMAGE=ubuntu:24.04
|
||||
ARG DEV_IMAGE=ghcr.io/tig-foundation/tig-monorepo/dev
|
||||
ARG CHALLENGE
|
||||
|
||||
FROM ${DEV_IMAGE} AS dev
|
||||
FROM ghcr.io/tig-foundation/tig-monorepo/${CHALLENGE}/dev AS dev
|
||||
|
||||
FROM ${BASE_IMAGE}
|
||||
|
||||
ARG CHALLENGE
|
||||
ENV CHALLENGE=${CHALLENGE}
|
||||
RUN if [ -z "$CHALLENGE" ]; then echo "Error: '--build-arg CHALLENGE' must be set." && exit 1; fi
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt update && apt install -y python3 python3-pip
|
||||
RUN pip3 install requests --break-system-packages
|
||||
|
||||
COPY scripts/ /usr/local/bin/tig-scripts/
|
||||
RUN chmod +x /usr/local/bin/tig-scripts/*
|
||||
ENV PATH="/usr/local/bin/tig-scripts:${PATH}"
|
||||
|
||||
COPY --from=dev /usr/local/bin/tig-runtime /usr/local/bin/tig-runtime
|
||||
COPY --from=dev /usr/local/bin/tig-verifier /usr/local/bin/tig-verifier
|
||||
COPY --from=dev /usr/local/lib/rust /usr/local/lib/rust
|
||||
|
||||
RUN chmod +x /usr/local/bin/tig-runtime && \
|
||||
chmod +x /usr/local/bin/tig-verifier && \
|
||||
echo "export LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}:/usr/local/lib/rust\"" >> /etc/bash.bashrc
|
||||
|
||||
RUN apt update && apt install -y python3 python3-pip
|
||||
RUN pip3 install blake3 requests randomname --break-system-packages
|
||||
|
||||
COPY scripts/ /usr/local/bin/tig-scripts/
|
||||
RUN chmod +x /usr/local/bin/tig-scripts/*
|
||||
ENV PATH="/usr/local/bin/tig-scripts:${PATH}"
|
||||
|
||||
COPY tig-benchmarker /app
|
||||
chmod +x /usr/local/bin/tig-verifier
|
||||
ENV LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/usr/local/lib/rust"
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
@ -7,9 +7,13 @@ import requests
|
||||
import sys
|
||||
import tarfile
|
||||
|
||||
CHALLENGE = os.getenv("CHALLENGE")
|
||||
if CHALLENGE is None:
|
||||
print("CHALLENGE environment variable must be set!")
|
||||
sys.exit(1)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='TIG Algorithm Downloader')
|
||||
parser.add_argument('challenge', help="Challenge name or id")
|
||||
parser.add_argument('algorithm', help="Algorithm name or id")
|
||||
parser.add_argument('--out', default="tig-algorithms/lib", help="Output directory (default: tig-algorithms/lib)")
|
||||
parser.add_argument('--testnet', action='store_true', help="Use testnet API")
|
||||
@ -26,12 +30,12 @@ def main():
|
||||
c_id = next(
|
||||
(
|
||||
c['id'] for c in challenges
|
||||
if c['details']['name'] == args.challenge or c['id'] == args.challenge
|
||||
if c['details']['name'] == CHALLENGE
|
||||
),
|
||||
None
|
||||
)
|
||||
if c_id is None:
|
||||
print(f"Challenge '{args.challenge}' not found.")
|
||||
print(f"Challenge '{CHALLENGE}' not found.")
|
||||
sys.exit(1)
|
||||
|
||||
a_id = next(
|
||||
@ -44,7 +48,7 @@ def main():
|
||||
None
|
||||
)
|
||||
if a_id is None:
|
||||
print(f"Algorithm '{args.algorithm}' not found for challenge '{args.challenge}'.")
|
||||
print(f"Algorithm '{args.algorithm}' not found for challenge '{CHALLENGE}'.")
|
||||
sys.exit(1)
|
||||
|
||||
download_url = download_urls.get(a_id)
|
||||
@ -54,7 +58,7 @@ def main():
|
||||
|
||||
print(f"Downloading algorithm '{args.algorithm}' from {download_url}...")
|
||||
resp = requests.get(download_url, stream=True)
|
||||
output_dir = f"{args.out}/{args.challenge}"
|
||||
output_dir = f"{args.out}/{CHALLENGE}"
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
with tarfile.open(fileobj=io.BytesIO(resp.content), mode='r:gz') as tar:
|
||||
tar.extractall(path=output_dir)
|
||||
|
||||
@ -1,15 +1,17 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import io
|
||||
import os
|
||||
import requests
|
||||
import sys
|
||||
import tarfile
|
||||
|
||||
CHALLENGE = os.getenv("CHALLENGE")
|
||||
if CHALLENGE is None:
|
||||
print("CHALLENGE environment variable must be set!")
|
||||
sys.exit(1)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='TIG Algorithm Lister')
|
||||
parser.add_argument('challenge', help="Challenge name or id")
|
||||
parser.add_argument('--testnet', action='store_true', help="Use testnet API")
|
||||
|
||||
args = parser.parse_args()
|
||||
@ -24,12 +26,12 @@ def main():
|
||||
c_id = next(
|
||||
(
|
||||
c['id'] for c in challenges
|
||||
if c['details']['name'] == args.challenge or c['id'] == args.challenge
|
||||
if c['details']['name'] == CHALLENGE
|
||||
),
|
||||
None
|
||||
)
|
||||
if c_id is None:
|
||||
print(f"Challenge '{args.challenge}' not found.")
|
||||
print(f"Challenge '{CHALLENGE}' not found.")
|
||||
sys.exit(1)
|
||||
|
||||
algorithms = sorted([
|
||||
|
||||
@ -37,6 +37,11 @@ elif (VISIBLE_GPUS := os.environ.get("CUDA_VISIBLE_DEVICES", None)) is None:
|
||||
else:
|
||||
VISIBLE_GPUS = list(map(int, VISIBLE_GPUS.split(",")))
|
||||
|
||||
CHALLENGE = os.getenv("CHALLENGE")
|
||||
if CHALLENGE is None:
|
||||
print("CHALLENGE environment variable must be set!")
|
||||
sys.exit(1)
|
||||
|
||||
def now():
|
||||
return int(time.time() * 1000)
|
||||
|
||||
@ -44,7 +49,6 @@ def now():
|
||||
if __name__ == "__main__":
|
||||
tig_runtime_path = shutil.which("tig-runtime")
|
||||
parser = argparse.ArgumentParser(description="TIG Algorithm Tester")
|
||||
parser.add_argument("challenge", type=str, help="Challenge name")
|
||||
parser.add_argument("algorithm", type=str, help="Algorithm name")
|
||||
parser.add_argument("difficulty", type=str, help="JSON string of difficulty")
|
||||
parser.add_argument("--tig_runtime_path", type=str, default=tig_runtime_path, help=f"Path to tig-runtime executable (default: {tig_runtime_path})")
|
||||
@ -58,8 +62,8 @@ if __name__ == "__main__":
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
so_path = f"{args.lib_dir}/{args.challenge}/{CPU_ARCH}/{args.algorithm}.so"
|
||||
ptx_path = f"{args.lib_dir}/{args.challenge}/ptx/{args.algorithm}.ptx"
|
||||
so_path = f"{args.lib_dir}/{CHALLENGE}/{CPU_ARCH}/{args.algorithm}.so"
|
||||
ptx_path = f"{args.lib_dir}/{CHALLENGE}/ptx/{args.algorithm}.ptx"
|
||||
|
||||
if not os.path.exists(so_path):
|
||||
print(
|
||||
@ -93,10 +97,7 @@ f"""Library not found at {so_path}:
|
||||
"hypergraph": "c005",
|
||||
"optimiser": "c006",
|
||||
}
|
||||
challenge_id = challenge_ids.get(args.challenge, None)
|
||||
if challenge_id is None:
|
||||
print(f"Unknown challenge '{args.challenge}'. Choices: ({', '.join(challenge_ids.keys())})")
|
||||
sys.exit(1)
|
||||
challenge_id = challenge_ids[CHALLENGE]
|
||||
|
||||
settings = {"algorithm_id": "", "challenge_id": challenge_id, "difficulty": difficulty, "block_id": "", "player_id": ""}
|
||||
pool = ThreadPoolExecutor(max_workers=args.workers + 1)
|
||||
|
||||
@ -23,4 +23,14 @@ tig-challenges = { path = "../tig-challenges" }
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[features]
|
||||
cuda = ["cudarc", "tig-challenges/cuda"]
|
||||
cuda = ["cudarc"]
|
||||
c001 = ["tig-challenges/c001"]
|
||||
satisfiability = ["c001"]
|
||||
c002 = ["tig-challenges/c002"]
|
||||
vehicle_routing = ["c002"]
|
||||
c003 = ["tig-challenges/c003"]
|
||||
knapsack = ["c003"]
|
||||
c004 = ["cuda", "tig-challenges/c004"]
|
||||
vector_search = ["c004"]
|
||||
c005 = ["cuda", "tig-challenges/c005"]
|
||||
hypergraph = ["c005"]
|
||||
|
||||
@ -11,18 +11,23 @@ pub(crate) type HashSet<T> = std::collections::HashSet<T, RandomState>;
|
||||
|
||||
pub const BUILD_TIME_PATH: &str = env!("CARGO_MANIFEST_DIR");
|
||||
|
||||
pub mod knapsack;
|
||||
pub use knapsack as c003;
|
||||
#[cfg(feature = "c001")]
|
||||
pub mod satisfiability;
|
||||
#[cfg(feature = "c001")]
|
||||
pub use satisfiability as c001;
|
||||
#[cfg(feature = "c002")]
|
||||
pub mod vehicle_routing;
|
||||
#[cfg(feature = "c002")]
|
||||
pub use vehicle_routing as c002;
|
||||
|
||||
#[cfg(feature = "cuda")]
|
||||
#[cfg(feature = "c003")]
|
||||
pub mod knapsack;
|
||||
#[cfg(feature = "c003")]
|
||||
pub use knapsack as c003;
|
||||
#[cfg(feature = "c004")]
|
||||
pub mod vector_search;
|
||||
#[cfg(feature = "cuda")]
|
||||
#[cfg(feature = "c004")]
|
||||
pub use vector_search as c004;
|
||||
#[cfg(feature = "cuda")]
|
||||
#[cfg(feature = "c005")]
|
||||
pub mod hypergraph;
|
||||
#[cfg(feature = "cuda")]
|
||||
#[cfg(feature = "c005")]
|
||||
pub use hypergraph as c005;
|
||||
|
||||
@ -19,4 +19,14 @@ tig-algorithms = { path = "../tig-algorithms" }
|
||||
|
||||
[features]
|
||||
entry_point = []
|
||||
cuda = ["cudarc", "tig-algorithms/cuda", "tig-challenges/cuda"]
|
||||
cuda = ["cudarc"]
|
||||
c001 = ["tig-algorithms/c001", "tig-challenges/c001"]
|
||||
satisfiability = ["c001"]
|
||||
c002 = ["tig-algorithms/c002", "tig-challenges/c002"]
|
||||
vehicle_routing = ["c002"]
|
||||
c003 = ["tig-algorithms/c003", "tig-challenges/c003"]
|
||||
knapsack = ["c003"]
|
||||
c004 = ["cuda", "tig-algorithms/c004", "tig-challenges/c004"]
|
||||
vector_search = ["c004"]
|
||||
c005 = ["cuda", "tig-algorithms/c005", "tig-challenges/c005"]
|
||||
hypergraph = ["c005"]
|
||||
|
||||
48
tig-binary/scripts/build_algorithm
Normal file
48
tig-binary/scripts/build_algorithm
Normal file
@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Check if CHALLENGE environment variable is set
|
||||
if [ -z "$CHALLENGE" ]; then
|
||||
echo "Error: CHALLENGE environment variable is not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if ALGORITHM argument is provided
|
||||
if [ -z "$1" ]; then
|
||||
echo "Error: ALGORITHM argument is required."
|
||||
echo "Usage: $0 <ALGORITHM>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ALGORITHM="$1"
|
||||
|
||||
# Match CHALLENGE value
|
||||
case "$CHALLENGE" in
|
||||
satisfiability)
|
||||
echo "Building ALGORITHM '$ALGORITHM' for CHALLENGE 'satisfiability'"
|
||||
build_so $ALGORITHM
|
||||
;;
|
||||
vehicle_routing)
|
||||
echo "Building ALGORITHM '$ALGORITHM' for CHALLENGE 'vehicle_routing'"
|
||||
build_so $ALGORITHM
|
||||
;;
|
||||
knapsack)
|
||||
echo "Building ALGORITHM '$ALGORITHM' for CHALLENGE 'knapsack'"
|
||||
build_so $ALGORITHM
|
||||
;;
|
||||
vector_search)
|
||||
echo "Building ALGORITHM '$ALGORITHM' for CHALLENGE 'vector_search'"
|
||||
build_so $ALGORITHM
|
||||
build_ptx $ALGORITHM
|
||||
;;
|
||||
hypergraph)
|
||||
echo "Building ALGORITHM '$ALGORITHM' for CHALLENGE 'hypergraph'"
|
||||
build_so $ALGORITHM
|
||||
build_ptx $ALGORITHM
|
||||
;;
|
||||
*)
|
||||
echo "Error: Invalid CHALLENGE value. Must be one of: satisfiability, knapsack, vehicle_routing, vector_search, hypergraph"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@ -3,11 +3,15 @@
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
CHALLENGE = os.getenv("CHALLENGE")
|
||||
if CHALLENGE is None:
|
||||
print("CHALLENGE environment variable must be set!")
|
||||
sys.exit(1)
|
||||
|
||||
# Import the dictionary from ptx_instructions.py
|
||||
instruction_fuel_cost = {
|
||||
'add.u32': 2,
|
||||
@ -232,12 +236,11 @@ $NORMAL_EXIT:
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Compile PTX with injected runtime signature')
|
||||
parser.add_argument('challenge', help='Challenge name')
|
||||
parser.add_argument('algorithm', help='Algorithm name')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
print(f"Compiling .ptx for {args.challenge}/{args.algorithm}")
|
||||
print(f"Compiling .ptx for {CHALLENGE}/{args.algorithm}")
|
||||
|
||||
framework_cu = "tig-binary/src/framework.cu"
|
||||
if not os.path.exists(framework_cu):
|
||||
@ -245,14 +248,14 @@ def main():
|
||||
f"Framework code does not exist @ '{framework_cu}'. This script must be run from the root of tig-monorepo"
|
||||
)
|
||||
|
||||
challenge_cu = f"tig-challenges/src/{args.challenge}.cu"
|
||||
challenge_cu = f"tig-challenges/src/{CHALLENGE}.cu"
|
||||
if not os.path.exists(challenge_cu):
|
||||
raise FileNotFoundError(
|
||||
f"Challenge code does not exist @ '{challenge_cu}'. Is the challenge name correct?"
|
||||
)
|
||||
|
||||
algorithm_cu = f"tig-algorithms/src/{args.challenge}/{args.algorithm}.cu"
|
||||
algorithm_cu2 = f"tig-algorithms/src/{args.challenge}/{args.algorithm}/benchmarker_outbound.cu"
|
||||
algorithm_cu = f"tig-algorithms/src/{CHALLENGE}/{args.algorithm}.cu"
|
||||
algorithm_cu2 = f"tig-algorithms/src/{CHALLENGE}/{args.algorithm}/benchmarker_outbound.cu"
|
||||
if not os.path.exists(algorithm_cu) and not os.path.exists(algorithm_cu2):
|
||||
raise FileNotFoundError(
|
||||
f"Algorithm code does not exist @ '{algorithm_cu}' or '{algorithm_cu2}'. Is the algorithm name correct?"
|
||||
@ -295,10 +298,8 @@ def main():
|
||||
parsed = parse_ptx_code(ptx_code)
|
||||
modified_code = inject_fuel_and_runtime_sig(parsed, kernels_to_ignore)
|
||||
|
||||
output_path = f"tig-algorithms/lib/{args.challenge}/ptx/{args.algorithm}.ptx"
|
||||
output_path = f"tig-algorithms/lib/{CHALLENGE}/ptx/{args.algorithm}.ptx"
|
||||
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
||||
# with open(output_path, 'w') as f:
|
||||
# f.writelines(ptx_code)
|
||||
with open(output_path, 'w') as f:
|
||||
f.writelines(modified_code)
|
||||
print(f"Wrote ptx to {output_path}")
|
||||
|
||||
@ -2,55 +2,34 @@
|
||||
|
||||
set -e
|
||||
|
||||
CUDA=false
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
echo "Error: Missing required arguments"
|
||||
echo "Usage: $0 CHALLENGE ALGORITHM [--cuda]"
|
||||
echo "Example: $0 knapsack dynamic"
|
||||
echo "Example with CUDA: $0 knapsack dynamic --cuda"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CHALLENGE="$1"
|
||||
ALGORITHM="$2"
|
||||
|
||||
shift 2
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--cuda)
|
||||
CUDA=true
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
echo "Usage: $0 CHALLENGE ALGORITHM [--cuda]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Check if CHALLENGE environment variable is set
|
||||
if [ -z "$CHALLENGE" ]; then
|
||||
echo "Error: CHALLENGE argument is empty"
|
||||
echo "Error: CHALLENGE environment variable is not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$ALGORITHM" ]; then
|
||||
echo "Error: ALGORITHM argument is empty"
|
||||
# Check if ALGORITHM argument is provided
|
||||
if [ -z "$1" ]; then
|
||||
echo "Error: ALGORITHM argument is required."
|
||||
echo "Usage: $0 <ALGORITHM>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ALGORITHM="$1"
|
||||
|
||||
echo "Compiling .so for $CHALLENGE/$ALGORITHM"
|
||||
cp tig-binary/src/entry_point_template.rs tig-binary/src/entry_point.rs
|
||||
sed -i "s/{CHALLENGE}/$CHALLENGE/g" tig-binary/src/entry_point.rs
|
||||
sed -i "s/{ALGORITHM}/$ALGORITHM/g" tig-binary/src/entry_point.rs
|
||||
|
||||
if [ "$CUDA" = true ]; then
|
||||
FEATURES="entry_point cuda"
|
||||
else
|
||||
FEATURES="entry_point"
|
||||
fi
|
||||
FEATURES="entry_point $CHALLENGE"
|
||||
|
||||
ARCH=$(uname -m)
|
||||
RUST_TARGET=$(if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
|
||||
echo "aarch64-unknown-linux-gnu";
|
||||
else
|
||||
echo "x86_64-unknown-linux-gnu";
|
||||
fi)
|
||||
RUSTFLAGS="--emit=llvm-ir -C embed-bitcode=yes -C codegen-units=1 -C opt-level=3 -C lto=no -C debuginfo=2 -C relocation-model=pic" \
|
||||
cargo +nightly-2025-02-10 build \
|
||||
-p tig-binary \
|
||||
|
||||
@ -23,3 +23,13 @@ statrs = { version = "0.18.0" }
|
||||
|
||||
[features]
|
||||
cuda = ["cudarc"]
|
||||
c001 = []
|
||||
satisfiability = ["c001"]
|
||||
c002 = []
|
||||
vehicle_routing = ["c002"]
|
||||
c003 = []
|
||||
knapsack = ["c003"]
|
||||
c004 = ["cuda"]
|
||||
vector_search = ["c004"]
|
||||
c005 = ["cuda"]
|
||||
hypergraph = ["c005"]
|
||||
|
||||
@ -1,17 +1,22 @@
|
||||
pub const BUILD_TIME_PATH: &str = env!("CARGO_MANIFEST_DIR");
|
||||
|
||||
pub mod knapsack;
|
||||
pub use knapsack as c003;
|
||||
#[cfg(feature = "c001")]
|
||||
pub mod satisfiability;
|
||||
#[cfg(feature = "c001")]
|
||||
pub use satisfiability as c001;
|
||||
#[cfg(feature = "c002")]
|
||||
pub mod vehicle_routing;
|
||||
#[cfg(feature = "c002")]
|
||||
pub use vehicle_routing as c002;
|
||||
|
||||
#[cfg(feature = "cuda")]
|
||||
#[cfg(feature = "c003")]
|
||||
pub mod knapsack;
|
||||
#[cfg(feature = "c003")]
|
||||
pub use knapsack as c003;
|
||||
#[cfg(feature = "c004")]
|
||||
pub mod vector_search;
|
||||
#[cfg(feature = "cuda")]
|
||||
#[cfg(feature = "c004")]
|
||||
pub use vector_search as c004;
|
||||
#[cfg(feature = "cuda")]
|
||||
#[cfg(feature = "c005")]
|
||||
pub mod hypergraph;
|
||||
#[cfg(feature = "cuda")]
|
||||
#[cfg(feature = "c005")]
|
||||
pub use hypergraph as c005;
|
||||
|
||||
@ -21,4 +21,14 @@ tig-structs = { path = "../tig-structs" }
|
||||
tig-utils = { path = "../tig-utils" }
|
||||
|
||||
[features]
|
||||
cuda = ["cudarc", "tig-challenges/cuda"]
|
||||
cuda = ["cudarc"]
|
||||
c001 = ["tig-challenges/c001"]
|
||||
satisfiability = ["c001"]
|
||||
c002 = ["tig-challenges/c002"]
|
||||
vehicle_routing = ["c002"]
|
||||
c003 = ["tig-challenges/c003"]
|
||||
knapsack = ["c003"]
|
||||
c004 = ["cuda", "tig-challenges/c004"]
|
||||
vector_search = ["c004"]
|
||||
c005 = ["cuda", "tig-challenges/c005"]
|
||||
hypergraph = ["c005"]
|
||||
|
||||
@ -51,7 +51,6 @@ fn cli() -> Command {
|
||||
)
|
||||
.arg(
|
||||
arg!(--gpu [GPU] "Which GPU device to use")
|
||||
.default_value("0")
|
||||
.value_parser(clap::value_parser!(usize)),
|
||||
)
|
||||
}
|
||||
@ -68,7 +67,7 @@ fn main() {
|
||||
*matches.get_one::<u64>("fuel").unwrap(),
|
||||
matches.get_one::<PathBuf>("output").cloned(),
|
||||
matches.get_one::<bool>("compress").unwrap().clone(),
|
||||
matches.get_one::<usize>("gpu").unwrap().clone(),
|
||||
matches.get_one::<usize>("gpu").cloned(),
|
||||
) {
|
||||
eprintln!("Error: {}", e);
|
||||
std::process::exit(1);
|
||||
@ -80,13 +79,11 @@ pub fn compute_solution(
|
||||
rand_hash: String,
|
||||
nonce: u64,
|
||||
library_path: PathBuf,
|
||||
#[cfg(feature = "cuda")] ptx_path: Option<PathBuf>,
|
||||
#[cfg(not(feature = "cuda"))] _ptx_path: Option<PathBuf>,
|
||||
ptx_path: Option<PathBuf>,
|
||||
max_fuel: u64,
|
||||
output_file: Option<PathBuf>,
|
||||
compress: bool,
|
||||
#[cfg(feature = "cuda")] gpu_device: usize,
|
||||
#[cfg(not(feature = "cuda"))] _gpu_device: usize,
|
||||
gpu_device: Option<usize>,
|
||||
) -> Result<()> {
|
||||
let settings = load_settings(&settings);
|
||||
let seed = settings.calc_seed(&rand_hash, nonce);
|
||||
@ -97,7 +94,12 @@ pub fn compute_solution(
|
||||
let runtime_signature_ptr = unsafe { *library.get::<*mut u64>(b"__runtime_signature")? };
|
||||
unsafe { *runtime_signature_ptr = u64::from_be_bytes(seed[0..8].try_into().unwrap()) };
|
||||
|
||||
let (fuel_consumed, runtime_signature, solution, invalid_reason) = 'out_of_fuel: {
|
||||
let (fuel_consumed, runtime_signature, solution, invalid_reason): (
|
||||
u64,
|
||||
u64,
|
||||
Solution,
|
||||
Option<String>,
|
||||
) = 'out_of_fuel: {
|
||||
macro_rules! dispatch_challenge {
|
||||
($c:ident, cpu) => {{
|
||||
// library function may exit 87 if it runs out of fuel
|
||||
@ -138,11 +140,6 @@ pub fn compute_solution(
|
||||
}};
|
||||
|
||||
($c:ident, gpu) => {{
|
||||
#[cfg(not(feature = "cuda"))]
|
||||
panic!("tig-runtime was not compiled with '--features cuda'");
|
||||
|
||||
#[cfg(feature = "cuda")]
|
||||
{
|
||||
if ptx_path.is_none() {
|
||||
panic!("PTX file is required for GPU challenges.");
|
||||
}
|
||||
@ -154,9 +151,7 @@ pub fn compute_solution(
|
||||
Arc<CudaModule>,
|
||||
Arc<CudaStream>,
|
||||
&cudaDeviceProp,
|
||||
) -> Result<Option<$c::Solution>, String>>(
|
||||
b"entry_point"
|
||||
)?
|
||||
) -> Result<Option<$c::Solution>, String>>(b"entry_point")?
|
||||
};
|
||||
|
||||
let gpu_fuel_scale = 20; // scale fuel to loosely align with CPU
|
||||
@ -165,6 +160,11 @@ pub fn compute_solution(
|
||||
let max_fuel_hex = format!("0x{:016x}", max_fuel * gpu_fuel_scale);
|
||||
let modified_ptx = ptx_content.replace("0xdeadbeefdeadbeef", &max_fuel_hex);
|
||||
|
||||
let num_gpus = CudaContext::device_count()?;
|
||||
if num_gpus == 0 {
|
||||
panic!("No CUDA devices found");
|
||||
}
|
||||
let gpu_device = gpu_device.unwrap_or((nonce % num_gpus as u64) as usize);
|
||||
let ptx = Ptx::from_src(modified_ptx);
|
||||
let ctx = CudaContext::new(gpu_device)?;
|
||||
ctx.set_blocking_synchronize()?;
|
||||
@ -195,8 +195,7 @@ pub fn compute_solution(
|
||||
.launch(cfg)?;
|
||||
}
|
||||
|
||||
let result =
|
||||
solve_challenge_fn(&challenge, module.clone(), stream.clone(), &prop);
|
||||
let result = solve_challenge_fn(&challenge, module.clone(), stream.clone(), &prop);
|
||||
if result
|
||||
.as_ref()
|
||||
.is_err_and(|e| e.contains("ran out of fuel"))
|
||||
@ -249,12 +248,7 @@ pub fn compute_solution(
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.to_owned(),
|
||||
match challenge.verify_solution(
|
||||
&s,
|
||||
module.clone(),
|
||||
stream.clone(),
|
||||
&prop,
|
||||
) {
|
||||
match challenge.verify_solution(&s, module.clone(), stream.clone(), &prop) {
|
||||
Ok(_) => None,
|
||||
Err(e) => Some(e.to_string()),
|
||||
},
|
||||
@ -263,16 +257,40 @@ pub fn compute_solution(
|
||||
};
|
||||
|
||||
(fuel_consumed, runtime_signature, solution, invalid_reason)
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
match settings.challenge_id.as_str() {
|
||||
"c001" => dispatch_challenge!(c001, cpu),
|
||||
"c002" => dispatch_challenge!(c002, cpu),
|
||||
"c003" => dispatch_challenge!(c003, cpu),
|
||||
"c004" => dispatch_challenge!(c004, gpu),
|
||||
"c005" => dispatch_challenge!(c005, gpu),
|
||||
"c001" => {
|
||||
#[cfg(not(feature = "c001"))]
|
||||
panic!("tig-runtime was not compiled with '--features c001'");
|
||||
#[cfg(feature = "c001")]
|
||||
dispatch_challenge!(c001, cpu)
|
||||
}
|
||||
"c002" => {
|
||||
#[cfg(not(feature = "c002"))]
|
||||
panic!("tig-runtime was not compiled with '--features c002'");
|
||||
#[cfg(feature = "c002")]
|
||||
dispatch_challenge!(c002, cpu)
|
||||
}
|
||||
"c003" => {
|
||||
#[cfg(not(feature = "c003"))]
|
||||
panic!("tig-runtime was not compiled with '--features c003'");
|
||||
#[cfg(feature = "c003")]
|
||||
dispatch_challenge!(c003, cpu)
|
||||
}
|
||||
"c004" => {
|
||||
#[cfg(not(feature = "c004"))]
|
||||
panic!("tig-runtime was not compiled with '--features c004'");
|
||||
#[cfg(feature = "c004")]
|
||||
dispatch_challenge!(c004, gpu)
|
||||
}
|
||||
"c005" => {
|
||||
#[cfg(not(feature = "c005"))]
|
||||
panic!("tig-runtime was not compiled with '--features c005'");
|
||||
#[cfg(feature = "c005")]
|
||||
dispatch_challenge!(c005, gpu)
|
||||
}
|
||||
_ => panic!("Unsupported challenge"),
|
||||
}
|
||||
};
|
||||
|
||||
@ -19,4 +19,14 @@ tig-structs = { path = "../tig-structs" }
|
||||
tig-utils = { path = "../tig-utils" }
|
||||
|
||||
[features]
|
||||
cuda = ["cudarc", "tig-challenges/cuda"]
|
||||
cuda = ["cudarc"]
|
||||
c001 = ["tig-challenges/c001"]
|
||||
satisfiability = ["c001"]
|
||||
c002 = ["tig-challenges/c002"]
|
||||
vehicle_routing = ["c002"]
|
||||
c003 = ["tig-challenges/c003"]
|
||||
knapsack = ["c003"]
|
||||
c004 = ["cuda", "tig-challenges/c004"]
|
||||
vector_search = ["c004"]
|
||||
c005 = ["cuda", "tig-challenges/c005"]
|
||||
hypergraph = ["c005"]
|
||||
|
||||
@ -34,7 +34,6 @@ fn cli() -> Command {
|
||||
)
|
||||
.arg(
|
||||
arg!(--gpu [GPU] "Which GPU device to use")
|
||||
.default_value("0")
|
||||
.value_parser(clap::value_parser!(usize)),
|
||||
),
|
||||
)
|
||||
@ -59,7 +58,7 @@ fn main() {
|
||||
*sub_m.get_one::<u64>("NONCE").unwrap(),
|
||||
sub_m.get_one::<String>("SOLUTION").unwrap().clone(),
|
||||
sub_m.get_one::<PathBuf>("ptx").cloned(),
|
||||
sub_m.get_one::<usize>("gpu").unwrap().clone(),
|
||||
sub_m.get_one::<usize>("gpu").cloned(),
|
||||
),
|
||||
Some(("verify_merkle_proof", sub_m)) => verify_merkle_proof(
|
||||
sub_m.get_one::<String>("ROOT").unwrap().clone(),
|
||||
@ -78,7 +77,7 @@ pub fn verify_solution(
|
||||
nonce: u64,
|
||||
solution_path: String,
|
||||
ptx_path: Option<PathBuf>,
|
||||
gpu_device: usize,
|
||||
gpu_device: Option<usize>,
|
||||
) -> Result<()> {
|
||||
let settings = load_settings(&settings);
|
||||
let solution = load_solution(&solution_path);
|
||||
@ -86,48 +85,35 @@ pub fn verify_solution(
|
||||
|
||||
let mut err_msg = Option::<String>::None;
|
||||
|
||||
macro_rules! dispatch_challenges {
|
||||
( $( ($c:ident, $cpu_or_gpu:tt) ),+ $(,)? ) => {{
|
||||
match settings.challenge_id.as_str() {
|
||||
$(
|
||||
stringify!($c) => {
|
||||
dispatch_challenges!(@expand $c, $cpu_or_gpu);
|
||||
}
|
||||
)+
|
||||
_ => panic!("Unsupported challenge"),
|
||||
}
|
||||
}};
|
||||
|
||||
(@expand $c:ident, cpu) => {{
|
||||
let challenge = $c::Challenge::generate_instance(
|
||||
&seed,
|
||||
&settings.difficulty.into(),
|
||||
).unwrap();
|
||||
macro_rules! dispatch_challenge {
|
||||
($c:ident, cpu) => {{
|
||||
let challenge =
|
||||
$c::Challenge::generate_instance(&seed, &settings.difficulty.into()).unwrap();
|
||||
|
||||
match $c::Solution::try_from(solution) {
|
||||
Ok(solution) => {
|
||||
match challenge.verify_solution(&solution) {
|
||||
Ok(solution) => match challenge.verify_solution(&solution) {
|
||||
Ok(_) => println!("Solution is valid"),
|
||||
Err(e) => err_msg = Some(format!("Invalid solution: {}", e)),
|
||||
}
|
||||
},
|
||||
Err(_) => err_msg = Some(format!(
|
||||
Err(_) => {
|
||||
err_msg = Some(format!(
|
||||
"Invalid solution. Cannot convert to {}::Solution",
|
||||
stringify!($c)
|
||||
)),
|
||||
))
|
||||
}
|
||||
}
|
||||
}};
|
||||
|
||||
(@expand $c:ident, gpu) => {{
|
||||
#[cfg(not(feature = "cuda"))]
|
||||
panic!("tig-runtime was not compiled with '--features cuda'");
|
||||
|
||||
#[cfg(feature = "cuda")]
|
||||
{
|
||||
($c:ident, gpu) => {{
|
||||
if ptx_path.is_none() {
|
||||
panic!("PTX file is required for GPU challenges.");
|
||||
}
|
||||
|
||||
let num_gpus = CudaContext::device_count()?;
|
||||
if num_gpus == 0 {
|
||||
panic!("No CUDA devices found");
|
||||
}
|
||||
let gpu_device = gpu_device.unwrap_or((nonce % num_gpus as u64) as usize);
|
||||
let ptx = Ptx::from_file(ptx_path.unwrap());
|
||||
let ctx = CudaContext::new(gpu_device).unwrap();
|
||||
ctx.set_blocking_synchronize()?;
|
||||
@ -141,35 +127,68 @@ pub fn verify_solution(
|
||||
module.clone(),
|
||||
stream.clone(),
|
||||
&prop,
|
||||
).unwrap();
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
match $c::Solution::try_from(solution) {
|
||||
Ok(solution) => {
|
||||
match challenge.verify_solution(&solution, module.clone(), stream.clone(), &prop) {
|
||||
match challenge.verify_solution(
|
||||
&solution,
|
||||
module.clone(),
|
||||
stream.clone(),
|
||||
&prop,
|
||||
) {
|
||||
Ok(_) => {
|
||||
stream.synchronize()?;
|
||||
ctx.synchronize()?;
|
||||
println!("Solution is valid");
|
||||
},
|
||||
}
|
||||
Err(e) => err_msg = Some(format!("Invalid solution: {}", e)),
|
||||
}
|
||||
},
|
||||
Err(_) => err_msg = Some(format!(
|
||||
}
|
||||
Err(_) => {
|
||||
err_msg = Some(format!(
|
||||
"Invalid solution. Cannot convert to {}::Solution",
|
||||
stringify!($c)
|
||||
)),
|
||||
))
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
dispatch_challenges!(
|
||||
(c001, cpu),
|
||||
(c002, cpu),
|
||||
(c003, cpu),
|
||||
(c004, gpu),
|
||||
(c005, gpu)
|
||||
);
|
||||
match settings.challenge_id.as_str() {
|
||||
"c001" => {
|
||||
#[cfg(not(feature = "c001"))]
|
||||
panic!("tig-verifier was not compiled with '--features c001'");
|
||||
#[cfg(feature = "c001")]
|
||||
dispatch_challenge!(c001, cpu)
|
||||
}
|
||||
"c002" => {
|
||||
#[cfg(not(feature = "c002"))]
|
||||
panic!("tig-verifier was not compiled with '--features c002'");
|
||||
#[cfg(feature = "c002")]
|
||||
dispatch_challenge!(c002, cpu)
|
||||
}
|
||||
"c003" => {
|
||||
#[cfg(not(feature = "c003"))]
|
||||
panic!("tig-verifier was not compiled with '--features c003'");
|
||||
#[cfg(feature = "c003")]
|
||||
dispatch_challenge!(c003, cpu)
|
||||
}
|
||||
"c004" => {
|
||||
#[cfg(not(feature = "c004"))]
|
||||
panic!("tig-verifier was not compiled with '--features c004'");
|
||||
#[cfg(feature = "c004")]
|
||||
dispatch_challenge!(c004, gpu)
|
||||
}
|
||||
"c005" => {
|
||||
#[cfg(not(feature = "c005"))]
|
||||
panic!("tig-verifier was not compiled with '--features c005'");
|
||||
#[cfg(feature = "c005")]
|
||||
dispatch_challenge!(c005, gpu)
|
||||
}
|
||||
_ => panic!("Unsupported challenge"),
|
||||
}
|
||||
|
||||
if let Some(err_msg) = err_msg {
|
||||
eprintln!("Verification error: {}", err_msg);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user