sp1_sdk/cuda/
prove.rs

1//! # CUDA Proving
2//!
3//! This module provides a builder for proving a program on the CUDA.
4
5use anyhow::Result;
6use sp1_core_machine::io::SP1Stdin;
7use sp1_prover::{components::CpuProverComponents, SP1ProvingKey};
8
9use super::CudaProver;
10use crate::{Prover, SP1ProofMode, SP1ProofWithPublicValues};
11
12/// A builder for proving a program on the CUDA.
13///
14/// This builder provides a typed interface for configuring the SP1 RISC-V prover. The builder is
15/// used for only the [`crate::cuda::CudaProver`] client type.
16pub struct CudaProveBuilder<'a> {
17    pub(crate) prover: &'a CudaProver,
18    pub(crate) mode: SP1ProofMode,
19    pub(crate) pk: &'a SP1ProvingKey,
20    pub(crate) stdin: SP1Stdin,
21}
22
23impl CudaProveBuilder<'_> {
24    /// Set the proof kind to [`SP1ProofMode::Core`] mode.
25    ///
26    /// # Details
27    /// This is the default mode for the prover. The proofs grow linearly in size with the number
28    /// of cycles.
29    ///
30    /// # Example
31    /// ```rust,no_run
32    /// use sp1_sdk::{include_elf, Prover, ProverClient, SP1Stdin};
33    ///
34    /// let elf = &[1, 2, 3];
35    /// let stdin = SP1Stdin::new();
36    ///
37    /// let client = ProverClient::builder().cuda().build();
38    /// let (pk, vk) = client.setup(elf);
39    /// let builder = client.prove(&pk, &stdin).core().run();
40    /// ```
41    #[must_use]
42    pub fn core(mut self) -> Self {
43        self.mode = SP1ProofMode::Core;
44        self
45    }
46
47    /// Set the proof kind to [`SP1ProofMode::Compressed`] mode.
48    ///
49    /// # Details
50    /// This mode produces a proof that is of constant size, regardless of the number of cycles. It
51    /// takes longer to prove than [`SP1ProofMode::Core`] due to the need to recursively aggregate
52    /// proofs into a single proof.
53    ///
54    /// # Example
55    /// ```rust,no_run
56    /// use sp1_sdk::{include_elf, Prover, ProverClient, SP1Stdin};
57    ///
58    /// let elf = &[1, 2, 3];
59    /// let stdin = SP1Stdin::new();
60    ///
61    /// let client = ProverClient::builder().cuda().build();
62    /// let (pk, vk) = client.setup(elf);
63    /// let builder = client.prove(&pk, &stdin).compressed().run();
64    /// ```
65    #[must_use]
66    pub fn compressed(mut self) -> Self {
67        self.mode = SP1ProofMode::Compressed;
68        self
69    }
70
71    /// Set the proof mode to [`SP1ProofMode::Plonk`] mode.
72    ///
73    /// # Details
74    /// This mode produces a const size PLONK proof that can be verified on chain for roughly ~300k
75    /// gas. This mode is useful for producing a maximally small proof that can be verified on
76    /// chain. For more efficient SNARK wrapping, you can use the [`SP1ProofMode::Groth16`] mode but
77    /// this mode is more .
78    ///
79    /// # Example
80    /// ```rust,no_run
81    /// use sp1_sdk::{include_elf, Prover, ProverClient, SP1Stdin};
82    ///
83    /// let elf = &[1, 2, 3];
84    /// let stdin = SP1Stdin::new();
85    ///
86    /// let client = ProverClient::builder().cuda().build();
87    /// let (pk, vk) = client.setup(elf);
88    /// let builder = client.prove(&pk, &stdin).plonk().run();
89    /// ```
90    #[must_use]
91    pub fn plonk(mut self) -> Self {
92        self.mode = SP1ProofMode::Plonk;
93        self
94    }
95
96    /// Set the proof mode to [`SP1ProofMode::Groth16`] mode.
97    ///
98    /// # Details
99    /// This mode produces a Groth16 proof that can be verified on chain for roughly ~100k gas. This
100    /// mode is useful for producing a proof that can be verified on chain with minimal gas.
101    ///
102    /// # Example
103    /// ```rust,no_run
104    /// use sp1_sdk::{include_elf, Prover, ProverClient, SP1Stdin};
105    ///
106    /// let elf = &[1, 2, 3];
107    /// let stdin = SP1Stdin::new();
108    ///
109    /// let client = ProverClient::builder().cuda().build();
110    /// let (pk, vk) = client.setup(elf);
111    /// let builder = client.prove(&pk, &stdin).groth16().run();
112    /// ```
113    #[must_use]
114    pub fn groth16(mut self) -> Self {
115        self.mode = SP1ProofMode::Groth16;
116        self
117    }
118
119    /// Set the proof mode to the given [`SP1ProofMode`].
120    ///
121    /// # Details
122    /// This method is useful for setting the proof mode to a custom mode.
123    ///
124    /// # Example
125    /// ```rust,no_run
126    /// use sp1_sdk::{include_elf, Prover, ProverClient, SP1ProofMode, SP1Stdin};
127    ///
128    /// let elf = &[1, 2, 3];
129    /// let stdin = SP1Stdin::new();
130    ///
131    /// let client = ProverClient::builder().cuda().build();
132    /// let (pk, vk) = client.setup(elf);
133    /// let builder = client.prove(&pk, &stdin).mode(SP1ProofMode::Groth16).run();
134    /// ```
135    #[must_use]
136    pub fn mode(mut self, mode: SP1ProofMode) -> Self {
137        self.mode = mode;
138        self
139    }
140
141    /// Run the prover with the built arguments.
142    ///
143    /// # Details
144    /// This method will run the prover with the built arguments. If the prover fails to run, the
145    /// method will return an error.
146    ///
147    /// # Example
148    /// ```rust,no_run
149    /// use sp1_sdk::{include_elf, Prover, ProverClient, SP1Stdin};
150    ///
151    /// let elf = &[1, 2, 3];
152    /// let stdin = SP1Stdin::new();
153    ///
154    /// let client = ProverClient::builder().cuda().build();
155    /// let (pk, vk) = client.setup(elf);
156    /// let proof = client.prove(&pk, &stdin).run().unwrap();
157    /// ```
158    pub fn run(self) -> Result<SP1ProofWithPublicValues> {
159        let Self { prover, mode: kind, pk, stdin } = self;
160
161        // Dump the program and stdin to files for debugging if `SP1_DUMP` is set.
162        crate::utils::sp1_dump(&pk.elf, &stdin);
163
164        Prover::<CpuProverComponents>::prove(prover, pk, &stdin, kind)
165    }
166}