Device Functions#
Device functions can be accessed from instances of a descriptor NTT.
Standard NTT#
- __device__ void NTT::execute( )#
Performs an in-place forward NTT on
data.- Parameters:
data – Shared-memory buffer of length
N, populated byNTT::load()orNTT::load_to_mont(); must already be in Montgomery form. Used in place as both input and output. Must not be a global memory pointer. The forward NTT overwritesdatawith the result, in Montgomery form.twiddles – Precomputed forward twiddle table of length
N, in Montgomery form.p – Prime field modulus.
- __device__ void NTT::execute( )#
Performs an in-place inverse NTT on
data.- Parameters:
data – Shared-memory buffer of length
N, populated byNTT::load()orNTT::load_to_mont(); must already be in Montgomery form. Used in place as both input and output. Must not be a global memory pointer. The inverse NTT overwritesdatawith the result, in Montgomery form.inv_twiddles – Precomputed inverse twiddle table of length
N, in Montgomery form.p – Prime field modulus.
N_inv – Multiplicative inverse of
Nmodulop(N-1 modp), applied as the normalisation factor.
- __device__ void NTT::make_twiddles( )#
Writes
Nforward twiddle factors to the output buffertwiddlesfor primepand primitive rootg. Call inside a single-thread kernel (<<<1, 1>>>). The twiddle factors are produced in standard (non-Montgomery) form; callNTT::transform_twiddles_to_mont()afterwards to convert them to Montgomery form before use.- Parameters:
twiddles – Output buffer of length
N; on return it holds the forward twiddle table in standard form.p – Prime field modulus.
g – Primitive root modulo
pused to generate twiddles.
- __device__ void NTT::transform_twiddles_to_mont( )#
Converts a twiddle table from standard form to Montgomery form in place. Unlike
NTT::make_twiddles(), this is a blockwise function — call it from a kernel launched with a full block ofNTT::BlockDimthreads (not<<<1, 1>>>), with all threads in the block calling it collectively. Call this afterNTT::make_twiddles()before passing the twiddle table to any execute function.- Parameters:
twiddles – Twiddle table of length
Nto be converted in place; on return holds the twiddle table in Montgomery form.p – Prime field modulus.
Data Transfer#
These functions move polynomial data between global memory and the shared-memory workspace used
by NTT::execute(). load and store copy raw values without any domain
conversion — use load when the source data is already in Montgomery form, and store
when the result should remain in Montgomery form in global memory. Use load_to_mont /
store_from_mont to convert explicitly at the boundary.
-
__device__ void NTT::load(Precision *sdata, const Precision *data)#
Loads
Nelements from global memorydatainto the shared-memory workspacesdatawithout domain conversion. Use whendatais already in Montgomery form.- Parameters:
sdata – Shared-memory destination buffer of length
N.data – Global-memory source buffer of length
N.
- __device__ void NTT::load_to_mont(
- Precision *sdata,
- const Precision *data,
- const nttConst<Precision> ntt_const = nttConst<Precision>(),
Loads
Nelements from global memorydatainto the shared-memory workspacesdata, converting from standard to Montgomery form usingntt_const.- Parameters:
sdata – Shared-memory destination buffer of length
N.data – Global-memory source buffer of length
Nin standard (non-Montgomery) form.ntt_const – Montgomery constants for the prime. Construct with
nttConst<Precision>(p).
-
__device__ void NTT::store(Precision *sdata, Precision *data)#
Stores
Nelements from the shared-memory workspacesdatato global memorydatawithout domain conversion. Use when the result should remain in Montgomery form.- Parameters:
sdata – Shared-memory source buffer of length
N.data – Global-memory destination buffer of length
N.
- __device__ void NTT::store_from_mont( )#
Stores
Nelements from the shared-memory workspacesdatato global memorydata, converting from Montgomery to standard form usingntt_const.- Parameters:
sdata – Shared-memory source buffer of length
N.data – Global-memory destination buffer of length
N.ntt_const – Montgomery constants for the prime. Construct with
nttConst<Precision>(p).
Threadwise Montgomery Conversion#
These functions convert a single element between standard and Montgomery form.
Unlike NTT::load_to_mont() and NTT::store_from_mont(), which
cooperate across all threads in the block to convert the full N-element array,
these functions operate on one value per calling thread and can be called
independently without synchronisation. Use them for pointwise conversions where
only individual elements need to change domain.
- __device__ Precision NTT::to_mont( )#
Converts a single element
xfrom standard form to Montgomery form. Each calling thread converts its own element independently.- Parameters:
x – Element in standard (non-Montgomery) form.
ntt_const – Montgomery constants for the prime. Construct with
nttConst<Precision>(p).
- Returns:
xin Montgomery form.
- __device__ Precision NTT::from_mont( )#
Converts a single element
xfrom Montgomery form to standard form. Each calling thread converts its own element independently.- Parameters:
x – Element in Montgomery form.
ntt_const – Montgomery constants for the prime. Construct with
nttConst<Precision>(p).
- Returns:
xin standard (non-Montgomery) form.
Transformed-Domain Arithmetic#
Element-wise modular arithmetic on two NTT-transformed polynomials held in shared memory.
Both operands are assumed to be in Montgomery form, as produced by NTT::execute()
after a Montgomery-domain load. data1 is updated in place; data2 is read-only.
- __device__ void NTT::add( )#
Computes
data1[i] = (data1[i] + data2[i]) mod pfor alliin[0, N). Both buffers must be in Montgomery form.- Parameters:
data1 – In/out shared-memory buffer of length
Nin Montgomery form; updated in place.data2 – Read-only shared-memory buffer of length
Nin Montgomery form.p – Prime field modulus.
- __device__ void NTT::mul( )#
Computes
data1[i] = (data1[i] * data2[i]) mod pfor alliin[0, N). Both buffers must be in Montgomery form; the result is also in Montgomery form.- Parameters:
data1 – In/out shared-memory buffer of length
Nin Montgomery form; updated in place.data2 – Read-only shared-memory buffer of length
Nin Montgomery form.p – Prime field modulus.
- __device__ void NTT::sub( )#
Computes
data1[i] = (data1[i] - data2[i]) mod pfor alliin[0, N). Both buffers must be in Montgomery form.- Parameters:
data1 – In/out shared-memory buffer of length
Nin Montgomery form; updated in place.data2 – Read-only shared-memory buffer of length
Nin Montgomery form.p – Prime field modulus.
Staged NTT#
(Requires SubSize<M>() in the descriptor.)
- __device__ void NTT::stage_1_execute( )#
First pass of a two-stage forward NTT. Launch with
Mblocks; each block processesK = N/Mconsecutive elements. Requires shared memory offwd_stage_1_ntt_shared_workspace_size<N, M, Precision>().- Parameters:
data – Shared-memory buffer of size
K(= N/M), populated byNTT::stage_1_load()orNTT::stage_1_load_to_mont(); must already be in Montgomery form. Used in place as input and output. Must not be a global memory pointer.twiddles – Precomputed forward twiddle table for this pass, in Montgomery form.
p – Prime field modulus.
- __device__ void NTT::stage_2_execute( )#
Second pass of a two-stage forward NTT. Launch with
Kblocks; each block processesMstrided elements. Requiresfwd_stage_2_ntt_shared_workspace_size<N, M, Precision>().- Parameters:
data – Shared-memory buffer of size
M, populated byNTT::stage_2_load()from the stage 1 output, which is always in Montgomery form. Used in place as input and output. Must not be a global memory pointer.twiddles – Precomputed forward twiddle table for this pass, in Montgomery form.
p – Prime field modulus.
- __device__ void NTT::stage_1_execute( )
First pass of a two-stage inverse NTT. Launch with
Kblocks; each block processesMstrided elements. Requiresinv_stage_1_ntt_shared_workspace_size<N, M, Precision>().- Parameters:
data – Shared-memory buffer of size
M, populated byNTT::stage_1_load()orNTT::stage_1_load_to_mont(); must already be in Montgomery form. Used in place as input and output. Must not be a global memory pointer.inv_twiddles – Precomputed inverse twiddle table for this pass, in Montgomery form.
p – Prime field modulus.
- __device__ void NTT::stage_2_execute( )#
Second pass of a two-stage inverse NTT; applies the 1/N normalisation. Launch with
Mblocks; each block processesK = N/Mconsecutive elements. Requiresinv_stage_2_ntt_shared_workspace_size<N, M, Precision>().- Parameters:
data – Shared-memory buffer of size
K(= N/M), populated byNTT::stage_2_load()from the stage 1 output, which is always in Montgomery form. Used in place as input and output. Must not be a global memory pointer.inv_twiddles – Precomputed inverse twiddle table for this pass, in Montgomery form.
p – Prime field modulus.
N_inv – Multiplicative inverse of
Nmodulop(N-1 modp), applied as the normalisation factor.
Staged Data Transfer#
(Requires SubSize<M>() in the descriptor.)
These functions move polynomial data between global memory and the per-stage shared-memory
workspace. Direction is inferred from the descriptor: forward and inverse stages use different
access patterns (strided vs. contiguous) so the correct layout is selected automatically.
The id argument is the current block index (pass blockIdx.x).
Only the boundary transfers have domain-converting variants: stage_1_load_to_mont converts
standard-form input to Montgomery form on the way in, and stage_2_store_from_mont converts
back to standard form on the way out. stage_1_store and stage_2_load handle the
intermediate global-memory buffer between stage 1 and stage 2, which always stays in Montgomery
form, so there is no stage_1_store_from_mont or stage_2_load_to_mont — stage_2_load
always assumes its source is already in Montgomery form. stage_1_load and stage_2_store
likewise copy data without domain conversion — use them when data is already in or should remain
in Montgomery form.
- __device__ void NTT::stage_1_load( )#
Loads the sub-array for stage 1 from global memory
dataintosdatawithout domain conversion. Use whendatais already in Montgomery form.Forward (
Mblocks,K = N/Melements each): readsKstrided elementsdata[id + i*M].Inverse (
Kblocks,Melements each): readsMcontiguous elementsdata[id*M + i].
- Parameters:
sdata – Shared-memory destination buffer.
data – Global-memory source buffer of length
N.id – Block index (
blockIdx.x).
- __device__ void NTT::stage_1_load_to_mont(
- Precision *sdata,
- const Precision *data,
- const int id,
- const nttConst<Precision> ntt_const = nttConst<Precision>(),
Like
NTT::stage_1_load()but converts from standard to Montgomery form on load usingntt_const.- Parameters:
sdata – Shared-memory destination buffer.
data – Global-memory source buffer of length
Nin standard (non-Montgomery) form.id – Block index (
blockIdx.x).ntt_const – Montgomery constants for the prime. Construct with
nttConst<Precision>(p).
- __device__ void NTT::stage_1_store( )#
Stores the sub-array computed by stage 1 from
sdatato global memorydata.Forward: writes strided elements back to
data[id + i*M].Inverse: writes contiguous elements back to
data[id*M + i].
- Parameters:
sdata – Shared-memory source buffer.
data – Global-memory destination buffer of length
N.id – Block index (
blockIdx.x).
- __device__ void NTT::stage_2_load( )#
Loads the sub-array for stage 2 from global memory
dataintosdatawithout domain conversion.datais assumed to already be in Montgomery form — the intermediate buffer written bystage_1_storeafter stage 1 is always in Montgomery form, so there is nostage_2_load_to_montvariant.Forward (
Kblocks,Melements each): readsMcontiguous elementsdata[id*M + i].Inverse (
Mblocks,Kelements each): readsKstrided elementsdata[id + i*M].
- Parameters:
sdata – Shared-memory destination buffer.
data – Global-memory source buffer of length
N.id – Block index (
blockIdx.x).
- __device__ void NTT::stage_2_store( )#
Stores the sub-array computed by stage 2 from
sdatato global memorydatawithout domain conversion. Use when the result should remain in Montgomery form.Forward: writes contiguous elements back to
data[id*M + i].Inverse: writes strided elements back to
data[id + i*M].
- Parameters:
sdata – Shared-memory source buffer.
data – Global-memory destination buffer of length
N.id – Block index (
blockIdx.x).
- __device__ void NTT::stage_2_store_from_mont(
- Precision *sdata,
- Precision *data,
- const int id,
- const nttConst<Precision> ntt_const = nttConst<Precision>(),
Like
NTT::stage_2_store()but converts from Montgomery to standard form on store usingntt_const.- Parameters:
sdata – Shared-memory source buffer.
data – Global-memory destination buffer of length
N.id – Block index (
blockIdx.x).ntt_const – Montgomery constants for the prime. Construct with
nttConst<Precision>(p).