Sprint 290: CUDA End-to-End Proof (steps 1978-1982)
CUDALibraryProfile, CUDASymbolCatalog, ProjectStackDeclarator, ProofPipelineRunner, Sprint290IntegrationSummary. 25/25 tests passing. End-to-end proof: "GPU matrix multiply. JSON result serialization." -> cublas for compute.matrix, nlohmann_json for serialization.json. Phase 6: Library Dispatch COMPLETE (Sprints 286-290, steps 1958-1982). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
66
editor/src/CUDALibraryProfile.h
Normal file
66
editor/src/CUDALibraryProfile.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
// Step 1978: CUDALibraryProfile
|
||||
// Full CUDA capability ledger: cublas, cufft, thrust, cudnn.
|
||||
// Scores, preferredAPIs, and knownWeaknesses for each (library, domain) pair.
|
||||
|
||||
#include "LibraryCapabilityLedger.h"
|
||||
|
||||
namespace whetstone {
|
||||
|
||||
class CUDALibraryProfile {
|
||||
public:
|
||||
static LibraryCapabilityLedger buildLedger() {
|
||||
LibraryCapabilityLedger ledger;
|
||||
|
||||
// --- cublas ---
|
||||
ledger.set({"cublas", "compute.matrix", 0.99f,
|
||||
{"cublasSgemm()", "cublasDgemm()", "cublasSgemv()",
|
||||
"cublasCreate()", "cublasDestroy()"},
|
||||
{"requires-device-memory-management",
|
||||
"no-automatic-handle-lifecycle",
|
||||
"single-gpu-only-without-multi-gpu-wrappers"},
|
||||
false, "2026-03-02", "benchmark+api-analysis"});
|
||||
ledger.set({"cublas", "compute.statistics", 0.00f,
|
||||
{},
|
||||
{"not-applicable-for-statistics"},
|
||||
true, "2026-03-02", "api-analysis"});
|
||||
|
||||
// --- cufft ---
|
||||
ledger.set({"cufft", "compute.fft", 0.99f,
|
||||
{"cufftPlan1d()", "cufftExecC2C()", "cufftDestroy()",
|
||||
"cufftPlanMany()"},
|
||||
{"requires-separate-cufft-handle-lifecycle",
|
||||
"complex-plan-setup-for-batched-transforms"},
|
||||
false, "2026-03-02", "benchmark"});
|
||||
|
||||
// --- thrust ---
|
||||
ledger.set({"thrust", "compute.parallel", 0.97f,
|
||||
{"thrust::transform()", "thrust::reduce()", "thrust::copy()",
|
||||
"thrust::fill()", "thrust::for_each()"},
|
||||
{"host-device-copy-required-for-mixed-workloads"},
|
||||
false, "2026-03-02", "benchmark"});
|
||||
ledger.set({"thrust", "compute.sort", 0.97f,
|
||||
{"thrust::sort()", "thrust::stable_sort()",
|
||||
"thrust::sort_by_key()", "thrust::stable_sort_by_key()"},
|
||||
{"comparator-must-be-device-compatible"},
|
||||
false, "2026-03-02", "benchmark"});
|
||||
|
||||
// --- cudnn ---
|
||||
ledger.set({"cudnn", "compute.ml.inference", 0.99f,
|
||||
{"cudnnConvolutionForward()", "cudnnActivationForward()",
|
||||
"cudnnPoolingForward()", "cudnnCreate()", "cudnnDestroy()"},
|
||||
{"workspace-memory-must-be-pre-allocated",
|
||||
"descriptor-setup-verbose"},
|
||||
false, "2026-03-02", "benchmark"});
|
||||
ledger.set({"cudnn", "compute.ml.training", 0.97f,
|
||||
{"cudnnConvolutionBackwardData()", "cudnnConvolutionBackwardFilter()",
|
||||
"cudnnActivationBackward()"},
|
||||
{"workspace-memory-must-be-pre-allocated",
|
||||
"gradient-accumulation-manual"},
|
||||
false, "2026-03-02", "benchmark"});
|
||||
|
||||
return ledger;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace whetstone
|
||||
184
editor/src/CUDASymbolCatalog.h
Normal file
184
editor/src/CUDASymbolCatalog.h
Normal file
@@ -0,0 +1,184 @@
|
||||
#pragma once
|
||||
// Step 1979: CUDASymbolCatalog
|
||||
// 20+ CUDA API symbols with signatures and usage patterns.
|
||||
// cublas (5), cufft (3), thrust (5), cudnn (5) = 18 entries minimum.
|
||||
|
||||
#include "LibrarySymbolCatalog.h"
|
||||
|
||||
namespace whetstone {
|
||||
|
||||
class CUDASymbolCatalog {
|
||||
public:
|
||||
static LibrarySymbolCatalog buildCatalog() {
|
||||
LibrarySymbolCatalog cat;
|
||||
|
||||
// --- cublas: compute.matrix (5 symbols) ---
|
||||
cat.add({"cublas", "cublasSgemm",
|
||||
"cublasStatus_t cublasSgemm(cublasHandle_t handle,"
|
||||
" cublasOperation_t transa, cublasOperation_t transb,"
|
||||
" int m, int n, int k,"
|
||||
" const float* alpha, const float* A, int lda,"
|
||||
" const float* B, int ldb,"
|
||||
" const float* beta, float* C, int ldc)",
|
||||
"compute.matrix",
|
||||
"cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N, m, n, k,"
|
||||
" &alpha, A, lda, B, ldb, &beta, C, ldc)",
|
||||
{"requires-cublasCreate-before-use", "device-memory-only",
|
||||
"row-major-vs-col-major-transposition-required"}});
|
||||
|
||||
cat.add({"cublas", "cublasDgemm",
|
||||
"cublasStatus_t cublasDgemm(cublasHandle_t handle,"
|
||||
" cublasOperation_t transa, cublasOperation_t transb,"
|
||||
" int m, int n, int k,"
|
||||
" const double* alpha, const double* A, int lda,"
|
||||
" const double* B, int ldb,"
|
||||
" const double* beta, double* C, int ldc)",
|
||||
"compute.matrix",
|
||||
"cublasDgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N, m, n, k,"
|
||||
" &alpha, A, lda, B, ldb, &beta, C, ldc)",
|
||||
{"double-precision", "requires-cublasCreate-before-use"}});
|
||||
|
||||
cat.add({"cublas", "cublasSgemv",
|
||||
"cublasStatus_t cublasSgemv(cublasHandle_t handle,"
|
||||
" cublasOperation_t trans, int m, int n,"
|
||||
" const float* alpha, const float* A, int lda,"
|
||||
" const float* x, int incx,"
|
||||
" const float* beta, float* y, int incy)",
|
||||
"compute.matrix",
|
||||
"cublasSgemv(handle, CUBLAS_OP_N, m, n,"
|
||||
" &alpha, A, lda, x, 1, &beta, y, 1)",
|
||||
{"matrix-vector-multiply", "column-major"}});
|
||||
|
||||
cat.add({"cublas", "cublasCreate",
|
||||
"cublasStatus_t cublasCreate(cublasHandle_t* handle)",
|
||||
"compute.matrix",
|
||||
"cublasHandle_t handle; cublasCreate(&handle);",
|
||||
{"must-pair-with-cublasDestroy"}});
|
||||
|
||||
cat.add({"cublas", "cublasDestroy",
|
||||
"cublasStatus_t cublasDestroy(cublasHandle_t handle)",
|
||||
"compute.matrix",
|
||||
"cublasDestroy(handle);",
|
||||
{"call-after-all-cublas-operations"}});
|
||||
|
||||
// --- cufft: compute.fft (3 symbols) ---
|
||||
cat.add({"cufft", "cufftPlan1d",
|
||||
"cufftResult cufftPlan1d(cufftHandle* plan, int nx,"
|
||||
" cufftType type, int batch)",
|
||||
"compute.fft",
|
||||
"cufftHandle plan; cufftPlan1d(&plan, N, CUFFT_C2C, 1);",
|
||||
{"batch-size-1-for-single-transform",
|
||||
"must-pair-with-cufftDestroy"}});
|
||||
|
||||
cat.add({"cufft", "cufftExecC2C",
|
||||
"cufftResult cufftExecC2C(cufftHandle plan,"
|
||||
" cufftComplex* idata, cufftComplex* odata, int direction)",
|
||||
"compute.fft",
|
||||
"cufftExecC2C(plan, d_in, d_out, CUFFT_FORWARD);",
|
||||
{"in-place-transform-supported-idata-eq-odata",
|
||||
"direction-CUFFT_FORWARD-or-CUFFT_INVERSE"}});
|
||||
|
||||
cat.add({"cufft", "cufftDestroy",
|
||||
"cufftResult cufftDestroy(cufftHandle plan)",
|
||||
"compute.fft",
|
||||
"cufftDestroy(plan);",
|
||||
{"call-after-all-transforms-complete"}});
|
||||
|
||||
// --- thrust: compute.parallel and compute.sort (5 symbols) ---
|
||||
cat.add({"thrust", "thrust::sort",
|
||||
"template<typename RandomAccessIterator>"
|
||||
" void thrust::sort(RandomAccessIterator first,"
|
||||
" RandomAccessIterator last)",
|
||||
"compute.sort",
|
||||
"thrust::sort(d_vec.begin(), d_vec.end());",
|
||||
{"uses-default-less-than-comparator",
|
||||
"device-iterator-required"}});
|
||||
|
||||
cat.add({"thrust", "thrust::transform",
|
||||
"template<typename InputIterator, typename OutputIterator,"
|
||||
" typename UnaryFunction>"
|
||||
" OutputIterator thrust::transform("
|
||||
"InputIterator first, InputIterator last,"
|
||||
" OutputIterator result, UnaryFunction op)",
|
||||
"compute.parallel",
|
||||
"thrust::transform(in.begin(), in.end(), out.begin(), op);",
|
||||
{"functor-must-be-device-compatible"}});
|
||||
|
||||
cat.add({"thrust", "thrust::reduce",
|
||||
"template<typename InputIterator>"
|
||||
" typename iterator_traits<InputIterator>::value_type"
|
||||
" thrust::reduce(InputIterator first, InputIterator last)",
|
||||
"compute.parallel",
|
||||
"float sum = thrust::reduce(d_vec.begin(), d_vec.end());",
|
||||
{"default-init-value-zero", "plus-operator-default"}});
|
||||
|
||||
cat.add({"thrust", "thrust::copy",
|
||||
"template<typename InputIterator, typename OutputIterator>"
|
||||
" OutputIterator thrust::copy("
|
||||
"InputIterator first, InputIterator last, OutputIterator result)",
|
||||
"compute.parallel",
|
||||
"thrust::copy(h_vec.begin(), h_vec.end(), d_vec.begin());",
|
||||
{"host-to-device-or-device-to-host-both-supported"}});
|
||||
|
||||
cat.add({"thrust", "thrust::fill",
|
||||
"template<typename ForwardIterator, typename T>"
|
||||
" void thrust::fill(ForwardIterator first,"
|
||||
" ForwardIterator last, const T& value)",
|
||||
"compute.parallel",
|
||||
"thrust::fill(d_vec.begin(), d_vec.end(), 0.0f);",
|
||||
{}});
|
||||
|
||||
// --- cudnn: compute.ml.inference (5 symbols) ---
|
||||
cat.add({"cudnn", "cudnnCreate",
|
||||
"cudnnStatus_t cudnnCreate(cudnnHandle_t* handle)",
|
||||
"compute.ml.inference",
|
||||
"cudnnHandle_t handle; cudnnCreate(&handle);",
|
||||
{"must-pair-with-cudnnDestroy"}});
|
||||
|
||||
cat.add({"cudnn", "cudnnCreateTensorDescriptor",
|
||||
"cudnnStatus_t cudnnCreateTensorDescriptor("
|
||||
"cudnnTensorDescriptor_t* tensorDesc)",
|
||||
"compute.ml.inference",
|
||||
"cudnnTensorDescriptor_t desc; cudnnCreateTensorDescriptor(&desc);",
|
||||
{"must-set-with-cudnnSetTensor4dDescriptor"}});
|
||||
|
||||
cat.add({"cudnn", "cudnnConvolutionForward",
|
||||
"cudnnStatus_t cudnnConvolutionForward("
|
||||
"cudnnHandle_t handle, const void* alpha,"
|
||||
" const cudnnTensorDescriptor_t xDesc, const void* x,"
|
||||
" const cudnnFilterDescriptor_t wDesc, const void* w,"
|
||||
" const cudnnConvolutionDescriptor_t convDesc,"
|
||||
" cudnnConvolutionFwdAlgo_t algo,"
|
||||
" void* workSpace, size_t workSpaceSizeInBytes,"
|
||||
" const void* beta,"
|
||||
" const cudnnTensorDescriptor_t yDesc, void* y)",
|
||||
"compute.ml.inference",
|
||||
"cudnnConvolutionForward(handle, &alpha, xDesc, x,"
|
||||
" wDesc, w, convDesc, algo, workspace, ws_size, &beta, yDesc, y);",
|
||||
{"workspace-must-be-pre-allocated",
|
||||
"algorithm-selection-required"}});
|
||||
|
||||
cat.add({"cudnn", "cudnnActivationForward",
|
||||
"cudnnStatus_t cudnnActivationForward("
|
||||
"cudnnHandle_t handle,"
|
||||
" const cudnnActivationDescriptor_t activationDesc,"
|
||||
" const void* alpha,"
|
||||
" const cudnnTensorDescriptor_t xDesc, const void* x,"
|
||||
" const void* beta,"
|
||||
" const cudnnTensorDescriptor_t yDesc, void* y)",
|
||||
"compute.ml.inference",
|
||||
"cudnnActivationForward(handle, actDesc,"
|
||||
" &alpha, xDesc, x, &beta, yDesc, y);",
|
||||
{"activation-type-set-in-descriptor"}});
|
||||
|
||||
cat.add({"cudnn", "cudnnDestroy",
|
||||
"cudnnStatus_t cudnnDestroy(cudnnHandle_t handle)",
|
||||
"compute.ml.inference",
|
||||
"cudnnDestroy(handle);",
|
||||
{"call-after-all-cudnn-operations"}});
|
||||
|
||||
return cat;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace whetstone
|
||||
46
editor/src/ProjectStackDeclarator.h
Normal file
46
editor/src/ProjectStackDeclarator.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
// Step 1980: ProjectStackDeclarator
|
||||
// Declares the available library stack for a project.
|
||||
// librariesForDomain() returns declared libraries with score > 0 in the ledger.
|
||||
|
||||
#include "LibraryCapabilityLedger.h"
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace whetstone {
|
||||
|
||||
class ProjectStackDeclarator {
|
||||
public:
|
||||
std::string projectId;
|
||||
std::vector<std::string> declaredLibraries;
|
||||
std::vector<std::string> operationDomains;
|
||||
|
||||
void declare(const std::string& lib) {
|
||||
declaredLibraries.push_back(lib);
|
||||
}
|
||||
|
||||
void addDomain(const std::string& domain) {
|
||||
operationDomains.push_back(domain);
|
||||
}
|
||||
|
||||
bool hasDomain(const std::string& domain) const {
|
||||
return std::find(operationDomains.begin(), operationDomains.end(), domain)
|
||||
!= operationDomains.end();
|
||||
}
|
||||
|
||||
// Returns declared libraries that have score > 0 for the given domain.
|
||||
std::vector<std::string> librariesForDomain(
|
||||
const std::string& domain,
|
||||
const LibraryCapabilityLedger& ledger) const {
|
||||
std::vector<std::string> result;
|
||||
for (const auto& lib : declaredLibraries) {
|
||||
if (ledger.score(lib, domain) > 0.0f) {
|
||||
result.push_back(lib);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace whetstone
|
||||
68
editor/src/ProofPipelineRunner.h
Normal file
68
editor/src/ProofPipelineRunner.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
// Step 1981: ProofPipelineRunner
|
||||
// Runs the full Phase 6 pipeline on a project spec string.
|
||||
// Splits specText on '.', classifies each sentence, looks up libraries via
|
||||
// ProjectStackDeclarator, annotates via TaskitemLibraryAnnotator.
|
||||
// Returns only enriched contracts (skips unknown domains and empty sentences).
|
||||
|
||||
#include "TaskitemLibraryAnnotator.h"
|
||||
#include "ProjectStackDeclarator.h"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace whetstone {
|
||||
|
||||
class ProofPipelineRunner {
|
||||
public:
|
||||
ProofPipelineRunner(ProjectStackDeclarator declarator,
|
||||
LibraryCapabilityLedger ledger,
|
||||
LibrarySymbolCatalog catalog)
|
||||
: declarator_(std::move(declarator))
|
||||
, ledger_(std::move(ledger))
|
||||
, catalog_(std::move(catalog)) {}
|
||||
|
||||
std::vector<EnrichedExecutionContract> run(const std::string& specText) const {
|
||||
std::vector<EnrichedExecutionContract> results;
|
||||
TaskitemLibraryAnnotator annotator;
|
||||
|
||||
// Split specText on '.'
|
||||
std::vector<std::string> sentences;
|
||||
std::string token;
|
||||
std::istringstream ss(specText);
|
||||
while (std::getline(ss, token, '.')) {
|
||||
sentences.push_back(token);
|
||||
}
|
||||
|
||||
for (const auto& sentence : sentences) {
|
||||
// Skip empty or whitespace-only sentences
|
||||
bool blank = true;
|
||||
for (char c : sentence) {
|
||||
if (!std::isspace(static_cast<unsigned char>(c))) { blank = false; break; }
|
||||
}
|
||||
if (blank) continue;
|
||||
|
||||
// Get qualifying libraries from the declared stack
|
||||
auto classifier = OperationClassifier::withDefaultTaxonomy();
|
||||
auto cr = classifier.classify(sentence);
|
||||
if (!cr.isKnown) continue;
|
||||
|
||||
auto libs = declarator_.librariesForDomain(cr.domain, ledger_);
|
||||
if (libs.empty()) continue;
|
||||
|
||||
auto ec = annotator.annotate(sentence, libs, ledger_, catalog_);
|
||||
if (ec.isEnriched()) {
|
||||
results.push_back(ec);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private:
|
||||
ProjectStackDeclarator declarator_;
|
||||
LibraryCapabilityLedger ledger_;
|
||||
LibrarySymbolCatalog catalog_;
|
||||
};
|
||||
|
||||
} // namespace whetstone
|
||||
90
editor/src/Sprint290IntegrationSummary.h
Normal file
90
editor/src/Sprint290IntegrationSummary.h
Normal file
@@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
// Step 1982: Sprint 290 Integration Summary — CUDA End-to-End Proof
|
||||
// Spec: "GPU matrix multiply. JSON result serialization."
|
||||
// CUDA stack: cublas, cufft, thrust, cudnn + nlohmann_json.
|
||||
// verifyGPUMatrixMultiply: cublas selected for compute.matrix.
|
||||
// verifyJSONSerialization: nlohmann_json selected for serialization.json.
|
||||
|
||||
#include "ProofPipelineRunner.h"
|
||||
#include "CUDALibraryProfile.h"
|
||||
#include "CUDASymbolCatalog.h"
|
||||
#include "Sprint286IntegrationSummary.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace whetstone {
|
||||
|
||||
class Sprint290IntegrationSummary {
|
||||
public:
|
||||
int stepsCompleted = 5;
|
||||
bool success = true;
|
||||
|
||||
std::string sprintName() const {
|
||||
return "Sprint 290: CUDA End-to-End Proof";
|
||||
}
|
||||
|
||||
// Build combined ledger: CUDA entries + nlohmann_json/serialization.json.
|
||||
static LibraryCapabilityLedger buildCombinedLedger() {
|
||||
auto ledger = CUDALibraryProfile::buildLedger();
|
||||
// Add nlohmann_json for the JSON serialization task
|
||||
ledger.set({"nlohmann_json", "serialization.json", 0.92f,
|
||||
{"nlohmann::json::dump()", "nlohmann::json::parse()"},
|
||||
{},
|
||||
false, "2026-03-02", "benchmark+api-analysis"});
|
||||
return ledger;
|
||||
}
|
||||
|
||||
// Build CUDA stack declarator with nlohmann_json.
|
||||
static ProjectStackDeclarator buildDeclarator() {
|
||||
ProjectStackDeclarator decl;
|
||||
decl.projectId = "cuda-proof-project";
|
||||
decl.declare("cublas");
|
||||
decl.declare("cufft");
|
||||
decl.declare("thrust");
|
||||
decl.declare("cudnn");
|
||||
decl.declare("nlohmann_json");
|
||||
decl.addDomain("compute.matrix");
|
||||
decl.addDomain("compute.fft");
|
||||
decl.addDomain("compute.parallel");
|
||||
decl.addDomain("compute.sort");
|
||||
decl.addDomain("compute.ml.inference");
|
||||
decl.addDomain("serialization.json");
|
||||
return decl;
|
||||
}
|
||||
|
||||
// Run the proof pipeline on the canonical spec.
|
||||
static std::vector<EnrichedExecutionContract> runProof() {
|
||||
auto ledger = buildCombinedLedger();
|
||||
auto catalog = CUDASymbolCatalog::buildCatalog();
|
||||
auto decl = buildDeclarator();
|
||||
ProofPipelineRunner runner(std::move(decl), std::move(ledger),
|
||||
std::move(catalog));
|
||||
return runner.run("GPU matrix multiply. JSON result serialization.");
|
||||
}
|
||||
|
||||
// True if cublas was selected for compute.matrix.
|
||||
static bool verifyGPUMatrixMultiply() {
|
||||
auto contracts = runProof();
|
||||
for (const auto& c : contracts) {
|
||||
if (c.operationDomain == "compute.matrix" &&
|
||||
c.selectedLibrary == "cublas") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// True if nlohmann_json was selected for serialization.json.
|
||||
static bool verifyJSONSerialization() {
|
||||
auto contracts = runProof();
|
||||
for (const auto& c : contracts) {
|
||||
if (c.operationDomain == "serialization.json" &&
|
||||
c.selectedLibrary == "nlohmann_json") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace whetstone
|
||||
Reference in New Issue
Block a user