mirror of
https://github.com/tig-pool-nk/tig-monorepo.git
synced 2026-02-21 17:47:22 +08:00
add verify_solution
This commit is contained in:
parent
3c5cfe359d
commit
f2e67939c0
@ -1,7 +1,7 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use clap::{arg, ArgAction, Command};
|
||||
use libloading::Library;
|
||||
use std::{fs, panic, path::PathBuf};
|
||||
use std::{fs, io::Read, panic, path::PathBuf};
|
||||
use tig_challenges::*;
|
||||
use tig_structs::core::{BenchmarkSettings, OutputData, Solution};
|
||||
use tig_utils::{compress_obj, dejsonify, jsonify};
|
||||
@ -58,6 +58,32 @@ fn cli() -> Command {
|
||||
.value_parser(clap::value_parser!(usize)),
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("verify_solution")
|
||||
.about("Verifies a solution")
|
||||
.arg(
|
||||
arg!(<SETTINGS> "Settings json string or path to json file")
|
||||
.value_parser(clap::value_parser!(String)),
|
||||
)
|
||||
.arg(
|
||||
arg!(<RAND_HASH> "A string used in seed generation")
|
||||
.value_parser(clap::value_parser!(String)),
|
||||
)
|
||||
.arg(arg!(<NONCE> "Nonce value").value_parser(clap::value_parser!(u64)))
|
||||
.arg(
|
||||
arg!(<SOLUTION> "Solution json string, path to json file, or '-' for stdin")
|
||||
.value_parser(clap::value_parser!(String)),
|
||||
)
|
||||
.arg(
|
||||
arg!(--ptx [PTX] "Path to a CUDA ptx file")
|
||||
.value_parser(clap::value_parser!(PathBuf)),
|
||||
)
|
||||
.arg(
|
||||
arg!(--gpu [GPU] "Which GPU device to use")
|
||||
.default_value("0")
|
||||
.value_parser(clap::value_parser!(usize)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
@ -75,6 +101,14 @@ fn main() {
|
||||
sub_m.get_one::<bool>("compress").unwrap().clone(),
|
||||
sub_m.get_one::<usize>("gpu").unwrap().clone(),
|
||||
),
|
||||
Some(("verify_solution", sub_m)) => verify_solution(
|
||||
sub_m.get_one::<String>("SETTINGS").unwrap().clone(),
|
||||
sub_m.get_one::<String>("RAND_HASH").unwrap().clone(),
|
||||
*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(),
|
||||
),
|
||||
_ => Err(anyhow!("Invalid subcommand")),
|
||||
} {
|
||||
eprintln!("Error: {}", e);
|
||||
@ -161,7 +195,6 @@ pub fn compute_solution(
|
||||
)?
|
||||
};
|
||||
|
||||
// Set the fuel limit in the PTX file
|
||||
let ptx_content = std::fs::read_to_string(&ptx_path)
|
||||
.map_err(|e| anyhow!("Failed to read PTX file: {}", e))?;
|
||||
let max_fuel_hex = format!("0x{:016x}", max_fuel);
|
||||
@ -275,6 +308,111 @@ pub fn compute_solution(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn verify_solution(
|
||||
settings: String,
|
||||
rand_hash: String,
|
||||
nonce: u64,
|
||||
solution_path: String,
|
||||
ptx_path: Option<PathBuf>,
|
||||
gpu_device: usize,
|
||||
) -> Result<()> {
|
||||
let settings = load_settings(&settings);
|
||||
let solution = load_solution(&solution_path);
|
||||
let seed = settings.calc_seed(&rand_hash, nonce);
|
||||
|
||||
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();
|
||||
|
||||
match $c::Solution::try_from(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!(
|
||||
"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")]
|
||||
{
|
||||
if ptx_path.is_none() {
|
||||
panic!("PTX file is required for GPU challenges.");
|
||||
}
|
||||
|
||||
let ptx_path = ptx_path.unwrap();
|
||||
let ptx_content = std::fs::read_to_string(&ptx_path)
|
||||
.map_err(|e| anyhow!("Failed to read PTX file: {}", e))?;
|
||||
|
||||
let ptx = cudarc::nvrtc::Ptx::from_src(ptx_content);
|
||||
let ctx = cudarc::driver::CudaContext::new(gpu_device).unwrap();
|
||||
ctx.set_blocking_synchronize()?;
|
||||
let module = ctx.load_module(ptx).unwrap();
|
||||
let stream = ctx.default_stream();
|
||||
let prop = cudarc::runtime::result::device::get_device_prop(gpu_device as i32).unwrap();
|
||||
|
||||
let challenge = $c::Challenge::generate_instance(
|
||||
seed,
|
||||
&settings.difficulty.into(),
|
||||
module.clone(),
|
||||
stream.clone(),
|
||||
&prop,
|
||||
).unwrap();
|
||||
|
||||
match $c::Solution::try_from(solution) {
|
||||
Ok(solution) => {
|
||||
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!(
|
||||
"Invalid solution. Cannot convert to {}::Solution",
|
||||
stringify!($c)
|
||||
)),
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
dispatch_challenges!((c001, cpu), (c002, cpu), (c003, cpu), (c004, gpu));
|
||||
|
||||
if let Some(err_msg) = err_msg {
|
||||
eprintln!("Verification error: {}", err_msg);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn load_settings(settings: &str) -> BenchmarkSettings {
|
||||
let settings = if settings.ends_with(".json") {
|
||||
fs::read_to_string(settings).unwrap_or_else(|_| {
|
||||
@ -300,42 +438,27 @@ pub fn load_module(path: &PathBuf) -> Result<Library> {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
fn load_solution(solution: &str) -> Solution {
|
||||
let solution = if solution == "-" {
|
||||
let mut buffer = String::new();
|
||||
std::io::stdin()
|
||||
.read_to_string(&mut buffer)
|
||||
.unwrap_or_else(|_| {
|
||||
eprintln!("Failed to read solution from stdin");
|
||||
std::process::exit(1);
|
||||
});
|
||||
buffer
|
||||
} else if solution.ends_with(".json") {
|
||||
fs::read_to_string(&solution).unwrap_or_else(|_| {
|
||||
eprintln!("Failed to read solution file: {}", solution);
|
||||
std::process::exit(1);
|
||||
})
|
||||
} else {
|
||||
solution.to_string()
|
||||
};
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <cuda_runtime.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#define FUELUSAGE_OK (0)
|
||||
#define FUELUSAGE_EXCEEDED (1)
|
||||
#define CHECK_FUEL_LIMIT asm("trap;")
|
||||
|
||||
__device__ u_int64_t gbl_SIGNATURE = 0; // Run-time signature
|
||||
__device__ u_int64_t gbl_FUELUSAGE = 0; // Fuel usage
|
||||
__device__ u_int64_t gbl_ERRORSTAT = 0; // Error status -- set to non-zero if fuel runs out
|
||||
|
||||
extern "C" __global__ void initialize_kernel()
|
||||
{
|
||||
gbl_ERRORSTAT = FUELUSAGE_OK;
|
||||
gbl_SIGNATURE = 0;
|
||||
gbl_FUELUSAGE = 0;
|
||||
|
||||
return;
|
||||
dejsonify::<Solution>(&solution).unwrap_or_else(|_| {
|
||||
eprintln!("Failed to parse solution");
|
||||
std::process::exit(1);
|
||||
})
|
||||
}
|
||||
|
||||
extern "C" __global__ void finalize_kernel(
|
||||
u_int64_t *fuelusage_ptr, // RETURNED: (64-bit) Fuel usage
|
||||
u_int64_t *signature_ptr, // RETURNED: (64-bit) Run-time signature
|
||||
u_int64_t *errorstat_ptr // RETURNED: (64-bit) Error status
|
||||
)
|
||||
{
|
||||
fuelusage_ptr[0] = gbl_FUELUSAGE; // RETURNED: (64-bit) Fuel usage
|
||||
signature_ptr[0] = gbl_SIGNATURE; // RETURNED: (64-bit) Run-time signature
|
||||
errorstat_ptr[0] = gbl_ERRORSTAT; // RETURNED: (64-bit) Error status -- set to non-zero if fuel runs out
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user