From 13f6b885e8936845ae8a08f5c84e995ae2e7a571 Mon Sep 17 00:00:00 2001 From: FiveMovesAhead Date: Mon, 6 Oct 2025 11:53:59 +0100 Subject: [PATCH] Add support for hyperparameters. --- Cargo.lock | 3 + tig-algorithms/Cargo.toml | 1 + tig-algorithms/src/hypergraph/template.cu | 38 ------- tig-algorithms/src/hypergraph/template.md | 40 +++++++ tig-algorithms/src/hypergraph/template.rs | 87 +++++---------- tig-algorithms/src/knapsack/template.md | 40 +++++++ tig-algorithms/src/knapsack/template.rs | 76 ++++--------- .../src/neuralnet_optimizer/template.cu | 32 ++++++ .../src/neuralnet_optimizer/template.md | 40 +++++++ .../src/neuralnet_optimizer/template.rs | 102 ++++++++++++++++++ tig-algorithms/src/satisfiability/template.md | 40 +++++++ tig-algorithms/src/satisfiability/template.rs | 65 +++++------ tig-algorithms/src/vector_search/template.cu | 38 ------- tig-algorithms/src/vector_search/template.md | 40 +++++++ tig-algorithms/src/vector_search/template.rs | 61 ++++------- .../src/vehicle_routing/template.md | 40 +++++++ .../src/vehicle_routing/template.rs | 76 ++++--------- tig-binary/Cargo.toml | 1 + tig-binary/src/entry_point_template.rs | 11 +- tig-protocol/src/context.rs | 2 + tig-protocol/src/contracts/benchmarks.rs | 3 + tig-runtime/src/main.rs | 27 ++++- tig-structs/src/core.rs | 1 + 23 files changed, 532 insertions(+), 332 deletions(-) create mode 100644 tig-algorithms/src/hypergraph/template.md create mode 100644 tig-algorithms/src/knapsack/template.md create mode 100644 tig-algorithms/src/neuralnet_optimizer/template.cu create mode 100644 tig-algorithms/src/neuralnet_optimizer/template.md create mode 100644 tig-algorithms/src/neuralnet_optimizer/template.rs create mode 100644 tig-algorithms/src/satisfiability/template.md create mode 100644 tig-algorithms/src/vector_search/template.md create mode 100644 tig-algorithms/src/vehicle_routing/template.md diff --git a/Cargo.lock b/Cargo.lock index c4913462..bf1cb794 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2039,6 +2039,7 @@ dependencies = [ "cudarc", "ndarray", "rand", + "serde_json", "tig-challenges", ] @@ -2048,6 +2049,7 @@ version = "0.1.0" dependencies = [ "anyhow", "cudarc", + "serde_json", "tig-algorithms", "tig-challenges", ] @@ -2062,6 +2064,7 @@ dependencies = [ "cudarc", "flate2", "ndarray", + "paste", "rand", "serde", "serde_json", diff --git a/tig-algorithms/Cargo.toml b/tig-algorithms/Cargo.toml index 2e7bba70..4939d6d0 100644 --- a/tig-algorithms/Cargo.toml +++ b/tig-algorithms/Cargo.toml @@ -17,6 +17,7 @@ rand = { version = "0.8.5", default-features = false, features = [ "std_rng", "small_rng", ] } +serde_json = { version = "1.0.113" } tig-challenges = { path = "../tig-challenges", features = [ "hide_verification", ] } diff --git a/tig-algorithms/src/hypergraph/template.cu b/tig-algorithms/src/hypergraph/template.cu index bd0c6dc4..17b1fb3f 100644 --- a/tig-algorithms/src/hypergraph/template.cu +++ b/tig-algorithms/src/hypergraph/template.cu @@ -1,41 +1,3 @@ -/*! -Copyright [year copyright work created] [name of copyright owner] - -Identity of Submitter [name of person or entity that submits the Work to TIG] - -UAI [UAI (if applicable)] - -Licensed under the TIG Inbound Game License v2.0 or (at your option) any later -version (the "License"); you may not use this file except in compliance with the -License. You may obtain a copy of the License at - -https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the specific -language governing permissions and limitations under the License. -*/ - -// REMOVE BELOW SECTION IF UNUSED -/* -REFERENCES AND ACKNOWLEDGMENTS - -This implementation is based on or inspired by existing work. Citations and -acknowledgments below: - -1. Academic Papers: - - [Author(s), "Paper Title", DOI (if available)] - -2. Code References: - - [Author(s), URL] - -3. Other: - - [Author(s), Details] - -*/ -// License must be the same as the rust code - // IMPORTANT NOTES: // 1. You can import any libraries available in nvidia/cuda:12.6.3-cudnn-devel-ubuntu24.04 // Example: diff --git a/tig-algorithms/src/hypergraph/template.md b/tig-algorithms/src/hypergraph/template.md new file mode 100644 index 00000000..0542b884 --- /dev/null +++ b/tig-algorithms/src/hypergraph/template.md @@ -0,0 +1,40 @@ +# TIG Code Submission + +## Submission Details + +* **Challenge Name:** hypergraph +* **Submission Name:** [name of code submission] +* **Copyright:** [year work created] [name of copyright owner] +* **Identity of Submitter:** [name of person or entity submitting the work to TIG] +* **Unique Algorithm Identifier (UAI):** [if applicable else null] + + +## References and Acknowledgments +*(If this implementation is based on or inspired by existing work, please include citations and acknowledgments below. Remove this section if unused.)* + +### 1. Academic Papers +- [Author(s)], *"[Paper Title]"*, DOI: [DOI or URL if available] + +### 2. Code References +- [Author(s)] – [URL] + +### 3. Other +- [Author(s)] – [Details or description] + + +## Additional Notes +*(Include any relevant context, usage notes, or implementation details here. Remove this section if unused.)* + + +## License + +The files in this folder are under the following licenses: +* TIG Benchmarker Outbound License +* TIG Commercial License +* TIG Inbound Game License +* TIG Innovator Outbound Game License +* TIG Open Data License +* TIG THV Game License + +Copies of the licenses can be obtained at: +https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses \ No newline at end of file diff --git a/tig-algorithms/src/hypergraph/template.rs b/tig-algorithms/src/hypergraph/template.rs index 81a61de2..59365079 100644 --- a/tig-algorithms/src/hypergraph/template.rs +++ b/tig-algorithms/src/hypergraph/template.rs @@ -1,40 +1,3 @@ -/*! -Copyright [year copyright work created] [name of copyright owner] - -Identity of Submitter [name of person or entity that submits the Work to TIG] - -UAI [UAI (if applicable)] - -Licensed under the TIG Inbound Game License v2.0 or (at your option) any later -version (the "License"); you may not use this file except in compliance with the -License. You may obtain a copy of the License at - -https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the specific -language governing permissions and limitations under the License. -*/ - -// REMOVE BELOW SECTION IF UNUSED -/* -REFERENCES AND ACKNOWLEDGMENTS - -This implementation is based on or inspired by existing work. Citations and -acknowledgments below: - -1. Academic Papers: - - [Author(s), "Paper Title", DOI (if available)] - -2. Code References: - - [Author(s), URL] - -3. Other: - - [Author(s), Details] - -*/ - // TIG's UI uses the pattern `tig_challenges::` to automatically detect your algorithm's challenge use crate::{seeded_hasher, HashMap, HashSet}; use anyhow::{anyhow, Result}; @@ -42,44 +5,43 @@ use cudarc::{ driver::{safe::LaunchConfig, CudaModule, CudaStream, PushKernelArg}, runtime::sys::cudaDeviceProp, }; +use serde_json::{Map, Value}; use std::sync::Arc; use tig_challenges::hypergraph::*; +#[derive(Serialize, Deserialize)] +pub struct Hyperparameters { + // Optionally define hyperparameters here. Example: + // pub param1: usize, + // pub param2: f64, +} + pub fn solve_challenge( challenge: &Challenge, + save_solution: &dyn Fn(&Solution) -> Result<()>, + hyperparameters: &Option>, module: Arc, stream: Arc, prop: &cudaDeviceProp, ) -> anyhow::Result> { - // Boiler plate for looping through and solving sub-instances - // You can modify this function if you want - let mut solution = Solution { - sub_solutions: Vec::new(), - }; - for sub_instance in &challenge.sub_instances { - match solve_sub_instance(sub_instance, module.clone(), stream.clone(), prop)? { - Some(sub_solution) => solution.sub_solutions.push(sub_solution), - None => return Ok(None), - } - } - Ok(Some(solution)) -} - -pub fn solve_sub_instance( - instance: &SubInstance, - module: Arc, - stream: Arc, - prop: &cudaDeviceProp, -) -> anyhow::Result> { // If you need random numbers, recommend using SmallRng with challenge.seed: - // use rand::{rngs::SmallRng, Rng, SeedableRng}; - // let mut rng = SmallRng::from_seed(challenge.seed); + // use rand::{rngs::SmallRng, Rng, SeedableRng}; + // let mut rng = SmallRng::from_seed(challenge.seed); // If you need HashMap or HashSet, make sure to use a deterministic hasher for consistent runtime_signature: // use crate::{seeded_hasher, HashMap, HashSet}; - // let hasher = seeded_hasher(&instance.seed); + // let hasher = seeded_hasher(&challenge.seed); // let map = HashMap::with_hasher(hasher); + // Support hyperparameters if needed: + // let hyperparameters = match hyperparameters { + // Some(hyperparameters) => { + // serde_json::from_value::(Value::Object(hyperparameters.clone())) + // .map_err(|e| anyhow!("Failed to parse hyperparameters: {}", e))? + // } + // None => Hyperparameters { /* set default values here */ }, + // }; + // when launching kernels, you should hardcode the LaunchConfig for determinism: // Example: // LaunchConfig { @@ -88,9 +50,10 @@ pub fn solve_sub_instance( // shared_mem_bytes: 400, // } + // use save_solution(&Solution) to save your solution. Overwrites any previous solution + // return Err() if your algorithm encounters an error - // return Ok(None) if your algorithm finds no solution or needs to exit early - // return Ok(SubSolution { .. }) if your algorithm finds a solution + // return Ok(()) if your algorithm is finished Err(anyhow!("Not implemented")) } diff --git a/tig-algorithms/src/knapsack/template.md b/tig-algorithms/src/knapsack/template.md new file mode 100644 index 00000000..22a0a4a9 --- /dev/null +++ b/tig-algorithms/src/knapsack/template.md @@ -0,0 +1,40 @@ +# TIG Code Submission + +## Submission Details + +* **Challenge Name:** knapsack +* **Submission Name:** [name of code submission] +* **Copyright:** [year work created] [name of copyright owner] +* **Identity of Submitter:** [name of person or entity submitting the work to TIG] +* **Unique Algorithm Identifier (UAI):** [if applicable else null] + + +## References and Acknowledgments +*(If this implementation is based on or inspired by existing work, please include citations and acknowledgments below. Remove this section if unused.)* + +### 1. Academic Papers +- [Author(s)], *"[Paper Title]"*, DOI: [DOI or URL if available] + +### 2. Code References +- [Author(s)] – [URL] + +### 3. Other +- [Author(s)] – [Details or description] + + +## Additional Notes +*(Include any relevant context, usage notes, or implementation details here. Remove this section if unused.)* + + +## License + +The files in this folder are under the following licenses: +* TIG Benchmarker Outbound License +* TIG Commercial License +* TIG Inbound Game License +* TIG Innovator Outbound Game License +* TIG Open Data License +* TIG THV Game License + +Copies of the licenses can be obtained at: +https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses \ No newline at end of file diff --git a/tig-algorithms/src/knapsack/template.rs b/tig-algorithms/src/knapsack/template.rs index 3a64e739..b8b4c6bf 100644 --- a/tig-algorithms/src/knapsack/template.rs +++ b/tig-algorithms/src/knapsack/template.rs @@ -1,61 +1,21 @@ -/*! -Copyright [year copyright work created] [name of copyright owner] - -Identity of Submitter [name of person or entity that submits the Work to TIG] - -UAI [UAI (if applicable)] - -Licensed under the TIG Inbound Game License v2.0 or (at your option) any later -version (the "License"); you may not use this file except in compliance with the -License. You may obtain a copy of the License at - -https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the specific -language governing permissions and limitations under the License. -*/ - -// REMOVE BELOW SECTION IF UNUSED -/* -REFERENCES AND ACKNOWLEDGMENTS - -This implementation is based on or inspired by existing work. Citations and -acknowledgments below: - -1. Academic Papers: - - [Author(s), "Paper Title", DOI (if available)] - -2. Code References: - - [Author(s), URL] - -3. Other: - - [Author(s), Details] - -*/ - // TIG's UI uses the pattern `tig_challenges::` to automatically detect your algorithm's challenge use crate::{seeded_hasher, HashMap, HashSet}; use anyhow::{anyhow, Result}; +use serde_json::{Map, Value}; use tig_challenges::knapsack::*; -pub fn solve_challenge(challenge: &Challenge) -> anyhow::Result> { - // Boiler plate for looping through and solving sub-instances - // You can modify this function if you want - let mut solution = Solution { - sub_solutions: Vec::new(), - }; - for sub_instance in &challenge.sub_instances { - match solve_sub_instance(sub_instance)? { - Some(sub_solution) => solution.sub_solutions.push(sub_solution), - None => return Ok(None), - } - } - Ok(Some(solution)) +#[derive(Serialize, Deserialize)] +pub struct Hyperparameters { + // Optionally define hyperparameters here. Example: + // pub param1: usize, + // pub param2: f64, } -pub fn solve_sub_instance(instance: &SubInstance) -> Result> { +pub fn solve_challenge( + challenge: &Challenge, + save_solution: &dyn Fn(&Solution) -> Result<()>, + hyperparameters: &Option>, +) -> Result<()> { // If you need random numbers, recommend using SmallRng with instance.seed: // use rand::{rngs::SmallRng, Rng, SeedableRng}; // let mut rng = SmallRng::from_seed(instance.seed); @@ -65,9 +25,19 @@ pub fn solve_sub_instance(instance: &SubInstance) -> Result> // let hasher = seeded_hasher(&instance.seed); // let map = HashMap::with_hasher(hasher); + // Support hyperparameters if needed: + // let hyperparameters = match hyperparameters { + // Some(hyperparameters) => { + // serde_json::from_value::(Value::Object(hyperparameters.clone())) + // .map_err(|e| anyhow!("Failed to parse hyperparameters: {}", e))? + // } + // None => Hyperparameters { /* set default values here */ }, + // }; + + // use save_solution(&Solution) to save your solution. Overwrites any previous solution + // return Err() if your algorithm encounters an error - // return Ok(None) if your algorithm finds no solution or needs to exit early - // return Ok(SubSolution { .. }) if your algorithm finds a solution + // return Ok(()) if your algorithm is finished Err(anyhow!("Not implemented")) } diff --git a/tig-algorithms/src/neuralnet_optimizer/template.cu b/tig-algorithms/src/neuralnet_optimizer/template.cu new file mode 100644 index 00000000..17b1fb3f --- /dev/null +++ b/tig-algorithms/src/neuralnet_optimizer/template.cu @@ -0,0 +1,32 @@ +// IMPORTANT NOTES: +// 1. You can import any libraries available in nvidia/cuda:12.6.3-cudnn-devel-ubuntu24.04 +// Example: +// #include +// #include +// #include +// #include +// +// 2. If you launch a kernel with multiple blocks, any writes should be to non-overlapping parts of the memory +// Example: +// arr[blockIdx.x] = 1; // This IS deterministic +// arr[0] = 1; // This is NOT deterministic +// +// 3. Any kernel available in .cu will be available here +// +// 4. If you need to use random numbers, you can use the CURAND library and seed it with challenge.seed. +// Example rust: +// let d_seed = stream.memcpy_stod(seed)?; +// stream +// .launch_builder(&my_kernel) +// .arg(&d_seed) +// ... +// +// Example cuda: +// extern "C" __global__ void my_kernel( +// const uint8_t *seed, +// ... +// ) { +// curandState state; +// curand_init(((uint64_t *)(seed))[0], 0, 0, &state); +// ... +// } diff --git a/tig-algorithms/src/neuralnet_optimizer/template.md b/tig-algorithms/src/neuralnet_optimizer/template.md new file mode 100644 index 00000000..3cdef2b0 --- /dev/null +++ b/tig-algorithms/src/neuralnet_optimizer/template.md @@ -0,0 +1,40 @@ +# TIG Code Submission + +## Submission Details + +* **Challenge Name:** neuralnet_optimizer +* **Submission Name:** [name of code submission] +* **Copyright:** [year work created] [name of copyright owner] +* **Identity of Submitter:** [name of person or entity submitting the work to TIG] +* **Unique Algorithm Identifier (UAI):** [if applicable else null] + + +## References and Acknowledgments +*(If this implementation is based on or inspired by existing work, please include citations and acknowledgments below. Remove this section if unused.)* + +### 1. Academic Papers +- [Author(s)], *"[Paper Title]"*, DOI: [DOI or URL if available] + +### 2. Code References +- [Author(s)] – [URL] + +### 3. Other +- [Author(s)] – [Details or description] + + +## Additional Notes +*(Include any relevant context, usage notes, or implementation details here. Remove this section if unused.)* + + +## License + +The files in this folder are under the following licenses: +* TIG Benchmarker Outbound License +* TIG Commercial License +* TIG Inbound Game License +* TIG Innovator Outbound Game License +* TIG Open Data License +* TIG THV Game License + +Copies of the licenses can be obtained at: +https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses \ No newline at end of file diff --git a/tig-algorithms/src/neuralnet_optimizer/template.rs b/tig-algorithms/src/neuralnet_optimizer/template.rs new file mode 100644 index 00000000..5177240d --- /dev/null +++ b/tig-algorithms/src/neuralnet_optimizer/template.rs @@ -0,0 +1,102 @@ +// TIG's UI uses the pattern `tig_challenges::` to automatically detect your algorithm's challenge +use anyhow::{anyhow, Result}; +use cudarc::{ + driver::{CudaModule, CudaSlice, CudaStream, LaunchConfig, PushKernelArg}, + runtime::sys::cudaDeviceProp, +}; +use serde_json::{Map, Value}; +use std::sync::Arc; +use tig_challenges::neuralnet_optimizer::*; + +#[derive(Serialize, Deserialize)] +pub struct Hyperparameters { + // Optionally define hyperparameters here. Example: + // pub param1: usize, + // pub param2: f64, +} + +const THREADS_PER_BLOCK: u32 = 1024; + +pub fn solve_challenge( + challenge: &Challenge, + save_solution: &dyn Fn(&Solution) -> Result<()>, + hyperparameters: &Option>, + module: Arc, + stream: Arc, + prop: &cudaDeviceProp, +) -> Result<()> { + // boilerplate for training loop + // recommend not modifying this function unless you have a good reason + let (solution, train_losses, val_losses) = training_loop( + challenge, + module, + stream, + prop, + optimizer_init_state, + optimizer_query_at_params, + optimizer_step, + )?; + save_solution(&solution)?; + + Ok() +} + +#[derive(Clone)] +struct OptimizerState { + // define any state your optimizer needs here +} + +impl OptimizerStateTrait for OptimizerState { + fn as_any(&self) -> &dyn std::any::Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn std::any::Any { + self + } + + fn box_clone(&self) -> Box { + Box::new(self.clone()) + } +} + +fn optimizer_init_state( + seed: [u8; 32], + param_sizes: &[usize], + stream: Arc, + module: Arc, + prop: &cudaDeviceProp, +) -> Result> { + // Ok(Box::new(OptimizerState { + // /* initialize state */ + // })) + Err(anyhow!("Not implemented")) +} + +fn optimizer_query_at_params( + optimizer_state: &dyn OptimizerStateTrait, + model_params: &[CudaSlice], + epoch: usize, + train_loss: Option, + val_loss: Option, + stream: Arc, + module: Arc, + prop: &cudaDeviceProp, +) -> Result>>> { + // optionally set model parameters to specific values before gradient calculation + Err(anyhow!("Not implemented")) +} + +fn optimizer_step( + optimizer_state: &mut dyn OptimizerStateTrait, + gradients: &[CudaSlice], + epoch: usize, + train_loss: Option, + val_loss: Option, + stream: Arc, + module: Arc, + prop: &cudaDeviceProp, +) -> Result>> { + // for each CudaSlice in gradients, calculate delta to adjust model parameters + Err(anyhow!("Not implemented")) +} diff --git a/tig-algorithms/src/satisfiability/template.md b/tig-algorithms/src/satisfiability/template.md new file mode 100644 index 00000000..88b2d489 --- /dev/null +++ b/tig-algorithms/src/satisfiability/template.md @@ -0,0 +1,40 @@ +# TIG Code Submission + +## Submission Details + +* **Challenge Name:** satisfiability +* **Submission Name:** [name of code submission] +* **Copyright:** [year work created] [name of copyright owner] +* **Identity of Submitter:** [name of person or entity submitting the work to TIG] +* **Unique Algorithm Identifier (UAI):** [if applicable else null] + + +## References and Acknowledgments +*(If this implementation is based on or inspired by existing work, please include citations and acknowledgments below. Remove this section if unused.)* + +### 1. Academic Papers +- [Author(s)], *"[Paper Title]"*, DOI: [DOI or URL if available] + +### 2. Code References +- [Author(s)] – [URL] + +### 3. Other +- [Author(s)] – [Details or description] + + +## Additional Notes +*(Include any relevant context, usage notes, or implementation details here. Remove this section if unused.)* + + +## License + +The files in this folder are under the following licenses: +* TIG Benchmarker Outbound License +* TIG Commercial License +* TIG Inbound Game License +* TIG Innovator Outbound Game License +* TIG Open Data License +* TIG THV Game License + +Copies of the licenses can be obtained at: +https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses \ No newline at end of file diff --git a/tig-algorithms/src/satisfiability/template.rs b/tig-algorithms/src/satisfiability/template.rs index 2c37063a..715df001 100644 --- a/tig-algorithms/src/satisfiability/template.rs +++ b/tig-algorithms/src/satisfiability/template.rs @@ -1,46 +1,21 @@ -/*! -Copyright [year copyright work created] [name of copyright owner] - -Identity of Submitter [name of person or entity that submits the Work to TIG] - -UAI [UAI (if applicable)] - -Licensed under the TIG Inbound Game License v2.0 or (at your option) any later -version (the "License"); you may not use this file except in compliance with the -License. You may obtain a copy of the License at - -https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the specific -language governing permissions and limitations under the License. -*/ - -// REMOVE BELOW SECTION IF UNUSED -/* -REFERENCES AND ACKNOWLEDGMENTS - -This implementation is based on or inspired by existing work. Citations and -acknowledgments below: - -1. Academic Papers: - - [Author(s), "Paper Title", DOI (if available)] - -2. Code References: - - [Author(s), URL] - -3. Other: - - [Author(s), Details] - -*/ - // TIG's UI uses the pattern `tig_challenges::` to automatically detect your algorithm's challenge use crate::{seeded_hasher, HashMap, HashSet}; use anyhow::{anyhow, Result}; +use serde_json::{Map, Value}; use tig_challenges::satisfiability::*; -pub fn solve_challenge(challenge: &Challenge) -> Result> { +#[derive(Serialize, Deserialize)] +pub struct Hyperparameters { + // Optionally define hyperparameters here. Example: + // pub param1: usize, + // pub param2: f64, +} + +pub fn solve_challenge( + challenge: &Challenge, + save_solution: &dyn Fn(&Solution) -> Result<()>, + hyperparameters: &Option>, +) -> Result<()> { // If you need random numbers, recommend using SmallRng with challenge.seed: // use rand::{rngs::SmallRng, Rng, SeedableRng}; // let mut rng = SmallRng::from_seed(challenge.seed); @@ -50,9 +25,19 @@ pub fn solve_challenge(challenge: &Challenge) -> Result> { // let hasher = seeded_hasher(&challenge.seed); // let map = HashMap::with_hasher(hasher); + // Support hyperparameters if needed: + // let hyperparameters = match hyperparameters { + // Some(hyperparameters) => { + // serde_json::from_value::(Value::Object(hyperparameters.clone())) + // .map_err(|e| anyhow!("Failed to parse hyperparameters: {}", e))? + // } + // None => Hyperparameters { /* set default values here */ }, + // }; + + // use save_solution(&Solution) to save your solution. Overwrites any previous solution + // return Err() if your algorithm encounters an error - // return Ok(None) if your algorithm finds no solution or needs to exit early - // return Ok(Solution { .. }) if your algorithm finds a solution + // return Ok(()) if your algorithm is finished Err(anyhow!("Not implemented")) } diff --git a/tig-algorithms/src/vector_search/template.cu b/tig-algorithms/src/vector_search/template.cu index b2c520d8..992b2601 100644 --- a/tig-algorithms/src/vector_search/template.cu +++ b/tig-algorithms/src/vector_search/template.cu @@ -1,41 +1,3 @@ -/*! -Copyright [year copyright work created] [name of copyright owner] - -Identity of Submitter [name of person or entity that submits the Work to TIG] - -UAI [UAI (if applicable)] - -Licensed under the TIG Inbound Game License v2.0 or (at your option) any later -version (the "License"); you may not use this file except in compliance with the -License. You may obtain a copy of the License at - -https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the specific -language governing permissions and limitations under the License. -*/ - -// REMOVE BELOW SECTION IF UNUSED -/* -REFERENCES AND ACKNOWLEDGMENTS - -This implementation is based on or inspired by existing work. Citations and -acknowledgments below: - -1. Academic Papers: - - [Author(s), "Paper Title", DOI (if available)] - -2. Code References: - - [Author(s), URL] - -3. Other: - - [Author(s), Details] - -*/ -// License must be the same as the rust code - // IMPORTANT NOTES: // 1. You can import any libraries available in nvidia/cuda:12.6.3-cudnn-devel-ubuntu24.04 // Example: diff --git a/tig-algorithms/src/vector_search/template.md b/tig-algorithms/src/vector_search/template.md new file mode 100644 index 00000000..d9f06e3b --- /dev/null +++ b/tig-algorithms/src/vector_search/template.md @@ -0,0 +1,40 @@ +# TIG Code Submission + +## Submission Details + +* **Challenge Name:** vector_search +* **Submission Name:** [name of code submission] +* **Copyright:** [year work created] [name of copyright owner] +* **Identity of Submitter:** [name of person or entity submitting the work to TIG] +* **Unique Algorithm Identifier (UAI):** [if applicable else null] + + +## References and Acknowledgments +*(If this implementation is based on or inspired by existing work, please include citations and acknowledgments below. Remove this section if unused.)* + +### 1. Academic Papers +- [Author(s)], *"[Paper Title]"*, DOI: [DOI or URL if available] + +### 2. Code References +- [Author(s)] – [URL] + +### 3. Other +- [Author(s)] – [Details or description] + + +## Additional Notes +*(Include any relevant context, usage notes, or implementation details here. Remove this section if unused.)* + + +## License + +The files in this folder are under the following licenses: +* TIG Benchmarker Outbound License +* TIG Commercial License +* TIG Inbound Game License +* TIG Innovator Outbound Game License +* TIG Open Data License +* TIG THV Game License + +Copies of the licenses can be obtained at: +https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses \ No newline at end of file diff --git a/tig-algorithms/src/vector_search/template.rs b/tig-algorithms/src/vector_search/template.rs index 86bdaf1b..0f357047 100644 --- a/tig-algorithms/src/vector_search/template.rs +++ b/tig-algorithms/src/vector_search/template.rs @@ -1,40 +1,3 @@ -/*! -Copyright [year copyright work created] [name of copyright owner] - -Identity of Submitter [name of person or entity that submits the Work to TIG] - -UAI [UAI (if applicable)] - -Licensed under the TIG Inbound Game License v2.0 or (at your option) any later -version (the "License"); you may not use this file except in compliance with the -License. You may obtain a copy of the License at - -https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the specific -language governing permissions and limitations under the License. -*/ - -// REMOVE BELOW SECTION IF UNUSED -/* -REFERENCES AND ACKNOWLEDGMENTS - -This implementation is based on or inspired by existing work. Citations and -acknowledgments below: - -1. Academic Papers: - - [Author(s), "Paper Title", DOI (if available)] - -2. Code References: - - [Author(s), URL] - -3. Other: - - [Author(s), Details] - -*/ - // TIG's UI uses the pattern `tig_challenges::` to automatically detect your algorithm's challenge use crate::{seeded_hasher, HashMap, HashSet}; use anyhow::{anyhow, Result}; @@ -42,14 +5,24 @@ use cudarc::{ driver::{safe::LaunchConfig, CudaModule, CudaStream, PushKernelArg}, runtime::sys::cudaDeviceProp, }; +use serde_json::{Map, Value}; use std::sync::Arc; use tig_challenges::vector_search::*; +#[derive(Serialize, Deserialize)] +pub struct Hyperparameters { + // Optionally define hyperparameters here. Example: + // pub param1: usize, + // pub param2: f64, +} + // when launching kernels, you should not exceed this const or else it may not be deterministic const MAX_THREADS_PER_BLOCK: u32 = 1024; pub fn solve_challenge( challenge: &Challenge, + save_solution: &dyn Fn(&Solution) -> Result<()>, + hyperparameters: &Option>, module: Arc, stream: Arc, prop: &cudaDeviceProp, @@ -63,6 +36,15 @@ pub fn solve_challenge( // let hasher = seeded_hasher(&challenge.seed); // let map = HashMap::with_hasher(hasher); + // Support hyperparameters if needed: + // let hyperparameters = match hyperparameters { + // Some(hyperparameters) => { + // serde_json::from_value::(Value::Object(hyperparameters.clone())) + // .map_err(|e| anyhow!("Failed to parse hyperparameters: {}", e))? + // } + // None => Hyperparameters { /* set default values here */ }, + // }; + // when launching kernels, you should hardcode the LaunchConfig for determinism: // Example: // LaunchConfig { @@ -71,9 +53,10 @@ pub fn solve_challenge( // shared_mem_bytes: 400, // } + // use save_solution(&Solution) to save your solution. Overwrites any previous solution + // return Err() if your algorithm encounters an error - // return Ok(None) if your algorithm finds no solution or needs to exit early - // return Ok(Solution { .. }) if your algorithm finds a solution + // return Ok(()) if your algorithm is finished Err(anyhow!("Not implemented")) } diff --git a/tig-algorithms/src/vehicle_routing/template.md b/tig-algorithms/src/vehicle_routing/template.md new file mode 100644 index 00000000..d637b1cf --- /dev/null +++ b/tig-algorithms/src/vehicle_routing/template.md @@ -0,0 +1,40 @@ +# TIG Code Submission + +## Submission Details + +* **Challenge Name:** vehicle_routing +* **Submission Name:** [name of code submission] +* **Copyright:** [year work created] [name of copyright owner] +* **Identity of Submitter:** [name of person or entity submitting the work to TIG] +* **Unique Algorithm Identifier (UAI):** [if applicable else null] + + +## References and Acknowledgments +*(If this implementation is based on or inspired by existing work, please include citations and acknowledgments below. Remove this section if unused.)* + +### 1. Academic Papers +- [Author(s)], *"[Paper Title]"*, DOI: [DOI or URL if available] + +### 2. Code References +- [Author(s)] – [URL] + +### 3. Other +- [Author(s)] – [Details or description] + + +## Additional Notes +*(Include any relevant context, usage notes, or implementation details here. Remove this section if unused.)* + + +## License + +The files in this folder are under the following licenses: +* TIG Benchmarker Outbound License +* TIG Commercial License +* TIG Inbound Game License +* TIG Innovator Outbound Game License +* TIG Open Data License +* TIG THV Game License + +Copies of the licenses can be obtained at: +https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses \ No newline at end of file diff --git a/tig-algorithms/src/vehicle_routing/template.rs b/tig-algorithms/src/vehicle_routing/template.rs index 2d323a4f..f85d9083 100644 --- a/tig-algorithms/src/vehicle_routing/template.rs +++ b/tig-algorithms/src/vehicle_routing/template.rs @@ -1,61 +1,21 @@ -/*! -Copyright [year copyright work created] [name of copyright owner] - -Identity of Submitter [name of person or entity that submits the Work to TIG] - -UAI [UAI (if applicable)] - -Licensed under the TIG Inbound Game License v2.0 or (at your option) any later -version (the "License"); you may not use this file except in compliance with the -License. You may obtain a copy of the License at - -https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the specific -language governing permissions and limitations under the License. -*/ - -// REMOVE BELOW SECTION IF UNUSED -/* -REFERENCES AND ACKNOWLEDGMENTS - -This implementation is based on or inspired by existing work. Citations and -acknowledgments below: - -1. Academic Papers: - - [Author(s), "Paper Title", DOI (if available)] - -2. Code References: - - [Author(s), URL] - -3. Other: - - [Author(s), Details] - -*/ - // TIG's UI uses the pattern `tig_challenges::` to automatically detect your algorithm's challenge use crate::{seeded_hasher, HashMap, HashSet}; use anyhow::{anyhow, Result}; +use serde_json::{Map, Value}; use tig_challenges::vehicle_routing::*; -pub fn solve_challenge(challenge: &Challenge) -> anyhow::Result> { - // Boiler plate for looping through and solving sub-instances - // You can modify this function if you want - let mut solution = Solution { - sub_solutions: Vec::new(), - }; - for sub_instance in &challenge.sub_instances { - match solve_sub_instance(sub_instance)? { - Some(sub_solution) => solution.sub_solutions.push(sub_solution), - None => return Ok(None), - } - } - Ok(Some(solution)) +#[derive(Serialize, Deserialize)] +pub struct Hyperparameters { + // Optionally define hyperparameters here. Example: + // pub param1: usize, + // pub param2: f64, } -pub fn solve_sub_instance(instance: &SubInstance) -> Result> { +pub fn solve_challenge( + challenge: &Challenge, + save_solution: &dyn Fn(&Solution) -> Result<()>, + hyperparameters: &Option>, +) -> Result<()> { // If you need random numbers, recommend using SmallRng with instance.seed: // use rand::{rngs::SmallRng, Rng, SeedableRng}; // let mut rng = SmallRng::from_seed(instance.seed); @@ -65,9 +25,19 @@ pub fn solve_sub_instance(instance: &SubInstance) -> Result> // let hasher = seeded_hasher(&instance.seed); // let map = HashMap::with_hasher(hasher); + // Support hyperparameters if needed: + // let hyperparameters = match hyperparameters { + // Some(hyperparameters) => { + // serde_json::from_value::(Value::Object(hyperparameters.clone())) + // .map_err(|e| anyhow!("Failed to parse hyperparameters: {}", e))? + // } + // None => Hyperparameters { /* set default values here */ }, + // }; + + // use save_solution(&Solution) to save your solution. Overwrites any previous solution + // return Err() if your algorithm encounters an error - // return Ok(None) if your algorithm finds no solution or needs to exit early - // return Ok(SubSolution { .. }) if your algorithm finds a solution + // return Ok(()) if your algorithm is finished Err(anyhow!("Not implemented")) } diff --git a/tig-binary/Cargo.toml b/tig-binary/Cargo.toml index ed905147..6604e637 100644 --- a/tig-binary/Cargo.toml +++ b/tig-binary/Cargo.toml @@ -15,6 +15,7 @@ anyhow = "1.0.81" cudarc = { git = "https://github.com/tig-foundation/cudarc.git", branch = "runtime-fuel/cudnn-cublas", features = [ "cuda-version-from-build-system", ], optional = true } +serde_json = { version = "1.0.113" } tig-challenges = { path = "../tig-challenges", features = [ "hide_verification", ] } diff --git a/tig-binary/src/entry_point_template.rs b/tig-binary/src/entry_point_template.rs index 901b17b4..7ecb9c85 100644 --- a/tig-binary/src/entry_point_template.rs +++ b/tig-binary/src/entry_point_template.rs @@ -1,4 +1,5 @@ use anyhow::{anyhow, Result}; +use serde_json::{Map, Value}; use std::panic::{catch_unwind, AssertUnwindSafe}; use tig_algorithms::{CHALLENGE}::{ALGORITHM}; use tig_challenges::{CHALLENGE}::*; @@ -16,11 +17,12 @@ use std::sync::Arc; #[unsafe(no_mangle)] pub fn entry_point( challenge: &Challenge, - save_solution: &dyn Fn(&Solution) -> Result<()> + save_solution: &dyn Fn(&Solution) -> Result<()>, + hyperparameters: &Option>, ) -> Result<()> { catch_unwind(AssertUnwindSafe(|| { - {ALGORITHM}::solve_challenge(challenge, save_solution) + {ALGORITHM}::solve_challenge(challenge, save_solution, hyperparameters) })).unwrap_or_else(|_| { Err(anyhow!("Panic occurred calling solve_challenge")) }) @@ -32,13 +34,14 @@ pub fn entry_point( pub fn entry_point( challenge: &Challenge, save_solution: &dyn Fn(&Solution) -> Result<()>, + hyperparameters: &Option>, module: Arc, stream: Arc, prop: &cudaDeviceProp, -) -> Result, String> +) -> Result<()> { catch_unwind(AssertUnwindSafe(|| { - {ALGORITHM}::solve_challenge(challenge, module, stream, prop) + {ALGORITHM}::solve_challenge(challenge, save_solution, hyperparameters, module, stream, prop) })).unwrap_or_else(|_| { Err(anyhow!("Panic occurred calling solve_challenge")) }) diff --git a/tig-protocol/src/context.rs b/tig-protocol/src/context.rs index 2d5701fe..4fad4a50 100644 --- a/tig-protocol/src/context.rs +++ b/tig-protocol/src/context.rs @@ -1,4 +1,5 @@ pub use anyhow::Result; +use serde_json::{Map, Value}; use std::collections::{HashMap, HashSet}; use tig_structs::{config::*, core::*}; @@ -71,6 +72,7 @@ pub trait Context { &self, settings: BenchmarkSettings, details: PrecommitDetails, + hyperparameters: Option>, ) -> Result; async fn get_proof_details(&self, benchmark_id: &String) -> Option; async fn get_proof_state(&self, benchmark_id: &String) -> Option; diff --git a/tig-protocol/src/contracts/benchmarks.rs b/tig-protocol/src/contracts/benchmarks.rs index 3f8a9e2c..03f160be 100644 --- a/tig-protocol/src/contracts/benchmarks.rs +++ b/tig-protocol/src/contracts/benchmarks.rs @@ -2,6 +2,7 @@ use crate::context::*; use anyhow::{anyhow, Result}; use logging_timer::time; use rand::{rngs::StdRng, seq::IteratorRandom, Rng, SeedableRng}; +use serde_json::{Map, Value}; use std::collections::HashSet; use tig_structs::core::*; use tig_utils::*; @@ -11,6 +12,7 @@ pub async fn submit_precommit( ctx: &T, player_id: String, settings: BenchmarkSettings, + hyperparameters: Option>, num_nonces: u64, seed: u64, ) -> Result { @@ -103,6 +105,7 @@ pub async fn submit_precommit( rand_hash: hex::encode(StdRng::seed_from_u64(seed).gen::<[u8; 16]>()), fee_paid: submission_fee, }, + hyperparameters, ) .await?; Ok(benchmark_id) diff --git a/tig-runtime/src/main.rs b/tig-runtime/src/main.rs index 4eed8a93..823d0808 100644 --- a/tig-runtime/src/main.rs +++ b/tig-runtime/src/main.rs @@ -1,6 +1,7 @@ use anyhow::{anyhow, Result}; use clap::{arg, Command}; use libloading::Library; +use serde_json::{Map, Value}; use std::{fs, panic, path::PathBuf}; use tig_challenges::*; use tig_structs::core::{BenchmarkSettings, CPUArchitecture, OutputData}; @@ -32,6 +33,10 @@ fn cli() -> Command { arg!( "Path to a shared object (*.so) file") .value_parser(clap::value_parser!(PathBuf)), ) + .arg( + arg!(--hyperparameters [HYPERPARAMETERS] "A json string of hyperparameters") + .value_parser(clap::value_parser!(String)), + ) .arg( arg!(--ptx [PTX] "Path to a CUDA ptx file") .value_parser(clap::value_parser!(PathBuf)), @@ -59,6 +64,7 @@ fn main() { matches.get_one::("RAND_HASH").unwrap().clone(), *matches.get_one::("NONCE").unwrap(), matches.get_one::("BINARY").unwrap().clone(), + matches.get_one("hyperparameters").cloned(), matches.get_one::("ptx").cloned(), *matches.get_one::("fuel").unwrap(), matches.get_one::("output").cloned(), @@ -74,6 +80,7 @@ pub fn compute_solution( rand_hash: String, nonce: u64, library_path: PathBuf, + hyperparameters: Option, ptx_path: Option, max_fuel: u64, output_folder: Option, @@ -82,6 +89,13 @@ pub fn compute_solution( let settings = load_settings(&settings); let seed = settings.calc_seed(&rand_hash, nonce); + let hyperparameters = hyperparameters.map(|x| { + dejsonify::>(&x).unwrap_or_else(|_| { + eprintln!("Failed to parse hyperparameters as JSON"); + std::process::exit(1); + }) + }); + let library = load_module(&library_path)?; let fuel_remaining_ptr = unsafe { *library.get::<*mut u64>(b"__fuel_remaining")? }; unsafe { *fuel_remaining_ptr = max_fuel }; @@ -100,10 +114,11 @@ pub fn compute_solution( ($c:ident, cpu) => {{ // library function may exit 87 if it runs out of fuel let solve_challenge_fn = unsafe { - library - .get:: Result<()>) -> Result<()>>( - b"entry_point", - )? + library.get:: Result<()>, + &Option>, + ) -> Result<()>>(b"entry_point")? }; let challenge = $c::Challenge::generate_instance(&seed, &settings.difficulty.into())?; @@ -130,7 +145,7 @@ pub fn compute_solution( fs::write(&output_file, jsonify(&output_data))?; Ok(()) }; - let result = solve_challenge_fn(&challenge, &save_solution_fn); + let result = solve_challenge_fn(&challenge, &save_solution_fn, &hyperparameters); if !output_file.exists() { save_solution_fn(&$c::Solution::new())?; } @@ -147,6 +162,7 @@ pub fn compute_solution( library.get:: anyhow::Result<()>, + &Option>, Arc, Arc, &cudaDeviceProp, @@ -247,6 +263,7 @@ pub fn compute_solution( let result = solve_challenge_fn( &challenge, &save_solution_fn, + &hyperparameters, module.clone(), stream.clone(), &prop, diff --git a/tig-structs/src/core.rs b/tig-structs/src/core.rs index 81eee4dc..a2dee790 100644 --- a/tig-structs/src/core.rs +++ b/tig-structs/src/core.rs @@ -88,6 +88,7 @@ serializable_struct_with_getters! { details: PrecommitDetails, settings: BenchmarkSettings, state: PrecommitState, + hyperparameters: Option>, } } serializable_struct_with_getters! {