mirror of
https://github.com/tig-pool-nk/tig-monorepo.git
synced 2026-02-21 17:37:21 +08:00
Add stdin support
This commit is contained in:
parent
30dc73db40
commit
19af8fe871
@ -1,7 +1,7 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use clap::{arg, Command};
|
||||
use libloading::Library;
|
||||
use serde_json::{Map, Value};
|
||||
use serde_json::{Map, Value, from_str as json_from_str};
|
||||
use std::{fs, panic, path::PathBuf};
|
||||
use tig_challenges::*;
|
||||
use tig_structs::core::{BenchmarkSettings, CPUArchitecture, OutputData};
|
||||
@ -16,21 +16,64 @@ use {
|
||||
std::sync::Arc,
|
||||
};
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct StdinConfig {
|
||||
settings: String,
|
||||
rand_hash: String,
|
||||
nonce: u64,
|
||||
binary: String,
|
||||
#[serde(default)]
|
||||
hyperparameters: Option<String>,
|
||||
#[serde(default)]
|
||||
ptx: Option<String>,
|
||||
#[serde(default = "default_fuel")]
|
||||
fuel: u64,
|
||||
#[serde(default)]
|
||||
output: Option<String>,
|
||||
#[serde(default)]
|
||||
gpu: Option<usize>,
|
||||
}
|
||||
|
||||
fn default_fuel() -> u64 {
|
||||
2000000000
|
||||
}
|
||||
|
||||
fn cli() -> Command {
|
||||
Command::new("tig-runtime")
|
||||
.about("Executes an algorithm on a single challenge instance")
|
||||
.arg_required_else_help(true)
|
||||
.arg(
|
||||
arg!(--stdin "Read configuration from stdin as JSON")
|
||||
.action(clap::ArgAction::SetTrue)
|
||||
.conflicts_with_all(&[
|
||||
"SETTINGS",
|
||||
"RAND_HASH",
|
||||
"NONCE",
|
||||
"BINARY",
|
||||
"hyperparameters",
|
||||
"ptx",
|
||||
"fuel",
|
||||
"output",
|
||||
"gpu",
|
||||
]),
|
||||
)
|
||||
.arg(
|
||||
arg!(<SETTINGS> "Settings json string or path to json file")
|
||||
.required_unless_present("stdin")
|
||||
.value_parser(clap::value_parser!(String)),
|
||||
)
|
||||
.arg(
|
||||
arg!(<RAND_HASH> "A string used in seed generation")
|
||||
.required_unless_present("stdin")
|
||||
.value_parser(clap::value_parser!(String)),
|
||||
)
|
||||
.arg(arg!(<NONCE> "Nonce value").value_parser(clap::value_parser!(u64)))
|
||||
.arg(
|
||||
arg!(<NONCE> "Nonce value")
|
||||
.required_unless_present("stdin")
|
||||
.value_parser(clap::value_parser!(u64))
|
||||
)
|
||||
.arg(
|
||||
arg!(<BINARY> "Path to a shared object (*.so) file")
|
||||
.required_unless_present("stdin")
|
||||
.value_parser(clap::value_parser!(PathBuf)),
|
||||
)
|
||||
.arg(
|
||||
@ -58,21 +101,50 @@ fn cli() -> Command {
|
||||
|
||||
fn main() {
|
||||
let matches = cli().get_matches();
|
||||
let result = if matches.get_flag("stdin") {
|
||||
let mut stdin_content = String::new();
|
||||
if let Err(e) = std::io::Read::read_to_string(&mut std::io::stdin(), &mut stdin_content) {
|
||||
eprintln!("Failed to read from stdin: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
if let Err(e) = compute_solution(
|
||||
matches.get_one::<String>("SETTINGS").unwrap().clone(),
|
||||
matches.get_one::<String>("RAND_HASH").unwrap().clone(),
|
||||
*matches.get_one::<u64>("NONCE").unwrap(),
|
||||
matches.get_one::<PathBuf>("BINARY").unwrap().clone(),
|
||||
matches.get_one("hyperparameters").cloned(),
|
||||
matches.get_one::<PathBuf>("ptx").cloned(),
|
||||
*matches.get_one::<u64>("fuel").unwrap(),
|
||||
matches.get_one::<PathBuf>("output").cloned(),
|
||||
matches.get_one::<usize>("gpu").cloned(),
|
||||
) {
|
||||
eprintln!("Runtime Error: {}", e);
|
||||
std::process::exit(84);
|
||||
}
|
||||
let config: StdinConfig = match json_from_str(&stdin_content) {
|
||||
Ok(cfg) => cfg,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to parse JSON from stdin: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
compute_solution(
|
||||
config.settings,
|
||||
config.rand_hash,
|
||||
config.nonce,
|
||||
PathBuf::from(config.binary),
|
||||
config.hyperparameters,
|
||||
config.ptx.map(PathBuf::from),
|
||||
config.fuel,
|
||||
config.output.map(PathBuf::from),
|
||||
config.gpu,
|
||||
)
|
||||
} else {
|
||||
compute_solution(
|
||||
matches.get_one::<String>("SETTINGS").unwrap().clone(),
|
||||
matches.get_one::<String>("RAND_HASH").unwrap().clone(),
|
||||
*matches.get_one::<u64>("NONCE").unwrap(),
|
||||
matches.get_one::<PathBuf>("BINARY").unwrap().clone(),
|
||||
matches.get_one("hyperparameters").cloned(),
|
||||
matches.get_one::<PathBuf>("ptx").cloned(),
|
||||
*matches.get_one::<u64>("fuel").unwrap(),
|
||||
matches.get_one::<PathBuf>("output").cloned(),
|
||||
matches.get_one::<usize>("gpu").cloned(),
|
||||
)
|
||||
};
|
||||
|
||||
if let Err(e) = result {
|
||||
eprintln!("Runtime Error: {}", e);
|
||||
std::process::exit(84);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compute_solution(
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use clap::{arg, Command};
|
||||
use serde_json::{Map, Value};
|
||||
use serde_json::{Map, Value, from_str as json_from_str};
|
||||
use std::{fs, io::Read, panic, path::PathBuf};
|
||||
use tig_challenges::*;
|
||||
use tig_structs::core::BenchmarkSettings;
|
||||
@ -9,21 +9,54 @@ use tig_utils::dejsonify;
|
||||
#[cfg(feature = "cuda")]
|
||||
use cudarc::{driver::CudaContext, nvrtc::Ptx, runtime::result::device::get_device_prop};
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct StdinConfig {
|
||||
settings: String,
|
||||
rand_hash: String,
|
||||
nonce: u64,
|
||||
solution: String,
|
||||
#[serde(default)]
|
||||
ptx: Option<String>,
|
||||
#[serde(default)]
|
||||
gpu: Option<usize>,
|
||||
#[serde(default)]
|
||||
verbose: bool,
|
||||
}
|
||||
|
||||
fn cli() -> Command {
|
||||
Command::new("tig-verifier")
|
||||
.about("Verifies a solution")
|
||||
.arg_required_else_help(true)
|
||||
.arg(
|
||||
arg!(--stdin "Read configuration from stdin as JSON")
|
||||
.action(clap::ArgAction::SetTrue)
|
||||
.conflicts_with_all(&[
|
||||
"SETTINGS",
|
||||
"RAND_HASH",
|
||||
"NONCE",
|
||||
"SOLUTION",
|
||||
"ptx",
|
||||
"gpu",
|
||||
"verbose",
|
||||
]),
|
||||
)
|
||||
.arg(
|
||||
arg!(<SETTINGS> "Settings json string or path to json file")
|
||||
.required_unless_present("stdin")
|
||||
.value_parser(clap::value_parser!(String)),
|
||||
)
|
||||
.arg(
|
||||
arg!(<RAND_HASH> "A string used in seed generation")
|
||||
.required_unless_present("stdin")
|
||||
.value_parser(clap::value_parser!(String)),
|
||||
)
|
||||
.arg(arg!(<NONCE> "Nonce value").value_parser(clap::value_parser!(u64)))
|
||||
.arg(
|
||||
arg!(<NONCE> "Nonce value")
|
||||
.required_unless_present("stdin")
|
||||
.value_parser(clap::value_parser!(u64))
|
||||
)
|
||||
.arg(
|
||||
arg!(<SOLUTION> "Solution base64 string, path to json file with solution field, or '-' for stdin")
|
||||
.required_unless_present("stdin")
|
||||
.value_parser(clap::value_parser!(String)),
|
||||
)
|
||||
.arg(arg!(--ptx [PTX] "Path to a CUDA ptx file").value_parser(clap::value_parser!(PathBuf)))
|
||||
@ -34,15 +67,43 @@ fn cli() -> Command {
|
||||
fn main() {
|
||||
let matches = cli().get_matches();
|
||||
|
||||
if let Err(e) = verify_solution(
|
||||
matches.get_one::<String>("SETTINGS").unwrap().clone(),
|
||||
matches.get_one::<String>("RAND_HASH").unwrap().clone(),
|
||||
*matches.get_one::<u64>("NONCE").unwrap(),
|
||||
matches.get_one::<String>("SOLUTION").unwrap().clone(),
|
||||
matches.get_one::<PathBuf>("ptx").cloned(),
|
||||
matches.get_one::<usize>("gpu").cloned(),
|
||||
matches.get_one::<bool>("verbose").cloned().unwrap_or(false),
|
||||
) {
|
||||
let result = if matches.get_flag("stdin") {
|
||||
let mut stdin_content = String::new();
|
||||
if let Err(e) = std::io::Read::read_to_string(&mut std::io::stdin(), &mut stdin_content) {
|
||||
eprintln!("Failed to read from stdin: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let config: StdinConfig = match json_from_str(&stdin_content) {
|
||||
Ok(cfg) => cfg,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to parse JSON from stdin: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
verify_solution(
|
||||
config.settings,
|
||||
config.rand_hash,
|
||||
config.nonce,
|
||||
config.solution,
|
||||
config.ptx.map(PathBuf::from),
|
||||
config.gpu,
|
||||
config.verbose,
|
||||
)
|
||||
} else {
|
||||
verify_solution(
|
||||
matches.get_one::<String>("SETTINGS").unwrap().clone(),
|
||||
matches.get_one::<String>("RAND_HASH").unwrap().clone(),
|
||||
*matches.get_one::<u64>("NONCE").unwrap(),
|
||||
matches.get_one::<String>("SOLUTION").unwrap().clone(),
|
||||
matches.get_one::<PathBuf>("ptx").cloned(),
|
||||
matches.get_one::<usize>("gpu").cloned(),
|
||||
matches.get_one::<bool>("verbose").cloned().unwrap_or(false),
|
||||
)
|
||||
};
|
||||
|
||||
if let Err(e) = result {
|
||||
eprintln!("Error: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user