constantine/tests/gpu/t_nvidia_fp.nim

134 lines
3.8 KiB
Nim
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Constantine
# Copyright (c) 2018-2019 Status Research & Development GmbH
# Copyright (c) 2020-Present Mamy André-Ratsimbazafy
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
# Standard library
std/[unittest, times],
# Internal
../../constantine/platforms/gpu/[llvm, nvidia, ir],
../../constantine/platforms/static_for,
../../constantine/math/config/curves,
../../constantine/math/io/io_bigints,
../../constantine/math/arithmetic,
../../constantine/math_gpu/fields_nvidia,
# Test utilities
../../helpers/prng_unsafe
var rng: RngState
let seed = uint32(getTime().toUnix() and (1'i64 shl 32 - 1)) # unixTime mod 2^32
rng.seed(seed)
echo "\n------------------------------------------------------\n"
echo "test_nvidia_fp xoshiro512** seed: ", seed
const Iters = 10
proc init(T: type CurveMetadata, asy: Assembler_LLVM, curve: static Curve, wordSize: WordSize): T =
CurveMetadata.init(
asy.ctx,
$curve & "_", wordSize,
fpBits = uint32 curve.getCurveBitwidth(),
fpMod = curve.Mod().toHex(),
frBits = uint32 curve.getCurveOrderBitwidth(),
frMod = curve.getCurveOrder().toHex())
proc genFieldAddPTX(asy: Assembler_LLVM, cm: CurveMetadata) =
let fpAdd = asy.field_add_gen(cm, fp)
asy.module.setCallableCudaKernel(fpAdd)
let frAdd = asy.field_add_gen(cm, fr)
asy.module.setCallableCudaKernel(frAdd)
# Init LLVM
# -------------------------
initializeFullNVPTXTarget()
initializePasses()
# Init GPU
# -------------------------
let cudaDevice = cudaDeviceInit()
var sm: tuple[major, minor: int32]
check cuDeviceGetAttribute(sm.major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, cudaDevice)
check cuDeviceGetAttribute(sm.minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, cudaDevice)
proc t_field_add(curve: static Curve) =
# Codegen
# -------------------------
let asy = Assembler_LLVM.new(bkNvidiaPTX, cstring("t_nvidia_" & $curve))
let cm32 = CurveMetadata.init(asy, curve, size32)
asy.genFieldAddPTX(cm32)
let cm64 = CurveMetadata.init(asy, curve, size64)
asy.genFieldAddPTX(cm64)
let ptx = asy.codegenNvidiaPTX(sm)
# GPU exec
# -------------------------
var cuCtx: CUcontext
var cuMod: CUmodule
check cuCtxCreate(cuCtx, 0, cudaDevice)
check cuModuleLoadData(cuMod, ptx)
defer:
check cuMod.cuModuleUnload()
check cuCtx.cuCtxDestroy()
let fpAdd32 = cuMod.getCudaKernel(cm32, opFpAdd)
let fpAdd64 = cuMod.getCudaKernel(cm64, opFpAdd)
let frAdd32 = cuMod.getCudaKernel(cm32, opFrAdd)
let frAdd64 = cuMod.getCudaKernel(cm64, opFrAdd)
# Fp
for i in 0 ..< Iters:
let a = rng.random_long01Seq(Fp[curve])
let b = rng.random_long01Seq(Fp[curve])
var rCPU, rGPU_32, rGPU_64: Fp[curve]
rCPU.sum(a, b)
fpAdd32.exec(rGPU_32, a, b)
fpAdd64.exec(rGPU_64, a, b)
doAssert bool(rCPU == rGPU_32)
doAssert bool(rCPU == rGPU_64)
# Fr
for i in 0 ..< Iters:
let a = rng.random_long01Seq(Fr[curve])
let b = rng.random_long01Seq(Fr[curve])
var rCPU, rGPU_32, rGPU_64: Fr[curve]
rCPU.sum(a, b)
frAdd32.exec(rGPU_32, a, b)
frAdd64.exec(rGPU_64, a, b)
doAssert bool(rCPU == rGPU_32)
doAssert bool(rCPU == rGPU_64)
proc main() =
const curves = [
P224,
BN254_Nogami,
BN254_Snarks,
Edwards25519,
Bandersnatch,
Pallas,
Vesta,
P256,
Secp256k1,
BLS12_377,
BLS12_381,
BW6_761
]
suite "[Nvidia GPU] Field Addition":
staticFor i, 0, curves.len:
const curve = curves[i]
test "Nvidia GPU field addition (𝔽p, 𝔽r) for " & $curve:
t_field_add(curve)
main()