Skip to content

Commit d4054c2

Browse files
hyperpolymathclaude
andcommitted
feat(julia): add GPU extractors for GPUVerify and Faial
Extracts __global__/__kernel function names as goals, __requires/ __ensures annotations as premises, __syncthreads/atomic* calls as tactics (GPUVerify); __shared__ declarations as premises, atomicAdd/ atomicCAS as tactics (Faial). Router entries added for "GPUVerify", "GPU", "gpu-verify", and "Faial" in extract_from_file. 53→55 named extractors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent d9a6bae commit d4054c2

1 file changed

Lines changed: 159 additions & 0 deletions

File tree

src/julia/extract_training_data.jl

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ function extract_from_file(prover::String, filepath::String)::Vector{ProofExampl
171171
examples = extract_hol_proofs(filepath, content)
172172
elseif prover in ["Rocq"]
173173
examples = extract_coq_proofs(filepath, content)
174+
elseif prover in ["GPUVerify", "GPU", "gpu-verify"]
175+
examples = extract_gpuverify_proofs(filepath, content)
176+
elseif prover == "Faial"
177+
examples = extract_faial_proofs(filepath, content)
174178
else
175179
# Generic extraction for other provers
176180
examples = extract_generic_proofs(prover, filepath, content)
@@ -3091,6 +3095,161 @@ function extract_hol_proofs(filepath::String, content::String)::Vector{ProofExam
30913095
return examples
30923096
end
30933097

3098+
"""
3099+
extract_gpuverify_proofs(filepath, content) -> Vector{ProofExample}
3100+
3101+
Extract kernel verification goals from CUDA/OpenCL source files.
3102+
3103+
Each `__global__ void <name>` (CUDA) or `__kernel void <name>` (OpenCL)
3104+
function becomes one ProofExample goal. Pre/post conditions expressed via
3105+
`__requires` and `__ensures` annotations become premises. `__syncthreads`
3106+
calls are collected as tactics since they are the canonical barrier primitive.
3107+
3108+
Corpus: GPUVerify testsuite and Rodinia/PolyBench-GPU CUDA benchmarks.
3109+
"""
3110+
function extract_gpuverify_proofs(filepath::String, content::String)::Vector{ProofExample}
3111+
examples = ProofExample[]
3112+
3113+
# Detect dialect (CUDA vs OpenCL)
3114+
is_cuda = occursin("__global__", content)
3115+
is_opencl = occursin("__kernel", content)
3116+
prover_name = "GPUVerify"
3117+
3118+
# Extract __requires and __ensures annotations as premises
3119+
premises = String[]
3120+
for m in eachmatch(r"__(requires|ensures)\s*\(([^)]+)\)", content)
3121+
push!(premises, string(m.captures[1], "(", m.captures[2], ")"))
3122+
end
3123+
3124+
# Collect __syncthreads() calls as proof tactics
3125+
tactics = String[]
3126+
if occursin("__syncthreads()", content)
3127+
push!(tactics, "__syncthreads()")
3128+
end
3129+
if occursin("barrier(CLK_LOCAL_MEM_FENCE)", content)
3130+
push!(tactics, "barrier(CLK_LOCAL_MEM_FENCE)")
3131+
end
3132+
if isempty(tactics)
3133+
push!(tactics, "auto")
3134+
end
3135+
3136+
# Match CUDA kernel declarations: __global__ void name(
3137+
if is_cuda
3138+
for m in eachmatch(r"__global__\s+void\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(", content)
3139+
kernel_name = m.captures[1]
3140+
push!(examples, ProofExample(
3141+
prover_name,
3142+
filepath,
3143+
kernel_name,
3144+
"race_free($kernel_name)",
3145+
copy(tactics),
3146+
copy(premises),
3147+
true
3148+
))
3149+
end
3150+
end
3151+
3152+
# Match OpenCL kernel declarations: __kernel void name(
3153+
if is_opencl
3154+
for m in eachmatch(r"__kernel\s+void\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(", content)
3155+
kernel_name = m.captures[1]
3156+
push!(examples, ProofExample(
3157+
prover_name,
3158+
filepath,
3159+
kernel_name,
3160+
"race_free($kernel_name)",
3161+
copy(tactics),
3162+
copy(premises),
3163+
true
3164+
))
3165+
end
3166+
end
3167+
3168+
# Fallback: no recognised kernel declarations found
3169+
if isempty(examples)
3170+
push!(examples, ProofExample(
3171+
prover_name,
3172+
filepath,
3173+
"unknown_kernel",
3174+
"race_free(unknown)",
3175+
tactics,
3176+
premises,
3177+
true
3178+
))
3179+
end
3180+
3181+
return examples
3182+
end
3183+
3184+
"""
3185+
extract_faial_proofs(filepath, content) -> Vector{ProofExample}
3186+
3187+
Extract data-race freedom goals from CUDA source files for the Faial
3188+
access-pattern analyser.
3189+
3190+
Each `__global__ void <name>` kernel becomes one ProofExample.
3191+
`__shared__` variable declarations are extracted as premises — shared
3192+
memory is the primary race surface Faial reasons about.
3193+
Synchronisation primitives (`__syncthreads`, `atomicAdd`, `atomicCAS`)
3194+
are collected as tactics.
3195+
3196+
Corpus: Faial tests/ directory and any CUDA kernel corpus.
3197+
"""
3198+
function extract_faial_proofs(filepath::String, content::String)::Vector{ProofExample}
3199+
examples = ProofExample[]
3200+
3201+
# Collect __shared__ declarations as premises (race surface)
3202+
premises = String[]
3203+
for line in split(content, '\n')
3204+
trimmed = strip(line)
3205+
if occursin("__shared__", trimmed)
3206+
push!(premises, trimmed)
3207+
end
3208+
end
3209+
3210+
# Collect synchronisation calls as tactics
3211+
tactics = String[]
3212+
if occursin("__syncthreads()", content)
3213+
push!(tactics, "__syncthreads()")
3214+
end
3215+
for m in eachmatch(r"(atomicAdd|atomicCAS|atomicExch)\s*\(", content)
3216+
push!(tactics, string(m.captures[1]))
3217+
end
3218+
if isempty(tactics)
3219+
push!(tactics, "auto")
3220+
end
3221+
tactics = unique(tactics)
3222+
3223+
# Match CUDA __global__ kernel declarations
3224+
for m in eachmatch(r"__global__\s+void\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(", content)
3225+
kernel_name = m.captures[1]
3226+
push!(examples, ProofExample(
3227+
"Faial",
3228+
filepath,
3229+
kernel_name,
3230+
"data_race_free($kernel_name)",
3231+
copy(tactics),
3232+
copy(premises),
3233+
true
3234+
))
3235+
end
3236+
3237+
# Fallback
3238+
if isempty(examples)
3239+
push!(examples, ProofExample(
3240+
"Faial",
3241+
filepath,
3242+
"unknown_kernel",
3243+
"data_race_free(unknown)",
3244+
tactics,
3245+
premises,
3246+
true
3247+
))
3248+
end
3249+
3250+
return examples
3251+
end
3252+
30943253
"""
30953254
Generic proof extraction (for simpler provers)
30963255
"""

0 commit comments

Comments
 (0)