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:
@@ -11144,3 +11144,18 @@ target_include_directories(step1976_test PRIVATE src)
|
||||
|
||||
add_executable(step1977_test tests/step1977_test.cpp)
|
||||
target_include_directories(step1977_test PRIVATE src)
|
||||
|
||||
add_executable(step1978_test tests/step1978_test.cpp)
|
||||
target_include_directories(step1978_test PRIVATE src)
|
||||
|
||||
add_executable(step1979_test tests/step1979_test.cpp)
|
||||
target_include_directories(step1979_test PRIVATE src)
|
||||
|
||||
add_executable(step1980_test tests/step1980_test.cpp)
|
||||
target_include_directories(step1980_test PRIVATE src)
|
||||
|
||||
add_executable(step1981_test tests/step1981_test.cpp)
|
||||
target_include_directories(step1981_test PRIVATE src)
|
||||
|
||||
add_executable(step1982_test tests/step1982_test.cpp)
|
||||
target_include_directories(step1982_test PRIVATE src)
|
||||
|
||||
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
|
||||
75
editor/tests/step1978_test.cpp
Normal file
75
editor/tests/step1978_test.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
// Step 1978: CUDALibraryProfile
|
||||
//
|
||||
// t1: buildLedger has cublas at 0.99 for compute.matrix
|
||||
// t2: cufft/compute.fft = 0.99
|
||||
// t3: thrust/compute.parallel = 0.97
|
||||
// t4: cudnn/compute.ml.inference = 0.99
|
||||
// t5: cublas/compute.statistics is not applicable (score 0 / notApplicable)
|
||||
|
||||
#include "CUDALibraryProfile.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace ws = whetstone;
|
||||
static int p = 0, f = 0;
|
||||
#define T(n) { std::cout << " " << #n << "... "; }
|
||||
#define P() { std::cout << "PASS\n"; ++p; }
|
||||
#define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; }
|
||||
#define C(c, m) if (!(c)) { F(m); return; }
|
||||
|
||||
void t1() {
|
||||
T(cublas_compute_matrix_0_99);
|
||||
auto ledger = ws::CUDALibraryProfile::buildLedger();
|
||||
C(ledger.score("cublas", "compute.matrix") == 0.99f, "cublas/compute.matrix = 0.99");
|
||||
auto rec = ledger.get("cublas", "compute.matrix");
|
||||
C(rec.has_value(), "record present");
|
||||
C(!rec->preferredAPIs.empty(), "preferredAPIs non-empty");
|
||||
bool hasSgemm = false;
|
||||
for (const auto& api : rec->preferredAPIs)
|
||||
if (api.find("cublasSgemm") != std::string::npos) hasSgemm = true;
|
||||
C(hasSgemm, "cublasSgemm in preferredAPIs");
|
||||
P();
|
||||
}
|
||||
|
||||
void t2() {
|
||||
T(cufft_compute_fft_0_99);
|
||||
auto ledger = ws::CUDALibraryProfile::buildLedger();
|
||||
C(ledger.score("cufft", "compute.fft") == 0.99f, "cufft/compute.fft = 0.99");
|
||||
auto rec = ledger.get("cufft", "compute.fft");
|
||||
C(rec.has_value(), "cufft record present");
|
||||
C(!rec->preferredAPIs.empty(), "cufft preferredAPIs non-empty");
|
||||
P();
|
||||
}
|
||||
|
||||
void t3() {
|
||||
T(thrust_compute_parallel_0_97);
|
||||
auto ledger = ws::CUDALibraryProfile::buildLedger();
|
||||
C(ledger.score("thrust", "compute.parallel") == 0.97f, "thrust/compute.parallel = 0.97");
|
||||
C(ledger.score("thrust", "compute.sort") == 0.97f, "thrust/compute.sort = 0.97");
|
||||
P();
|
||||
}
|
||||
|
||||
void t4() {
|
||||
T(cudnn_ml_inference_0_99);
|
||||
auto ledger = ws::CUDALibraryProfile::buildLedger();
|
||||
C(ledger.score("cudnn", "compute.ml.inference") == 0.99f, "cudnn/ml.inference = 0.99");
|
||||
C(ledger.score("cudnn", "compute.ml.training") == 0.97f, "cudnn/ml.training = 0.97");
|
||||
P();
|
||||
}
|
||||
|
||||
void t5() {
|
||||
T(cublas_statistics_not_applicable);
|
||||
auto ledger = ws::CUDALibraryProfile::buildLedger();
|
||||
// cublas/compute.statistics has notApplicable=true, score=0
|
||||
C(ledger.score("cublas", "compute.statistics") == 0.0f, "cublas/compute.statistics = 0");
|
||||
auto rec = ledger.get("cublas", "compute.statistics");
|
||||
C(rec.has_value(), "record exists");
|
||||
C(rec->notApplicable, "notApplicable = true");
|
||||
P();
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::cout << "Step 1978: CUDALibraryProfile\n";
|
||||
t1(); t2(); t3(); t4(); t5();
|
||||
std::cout << "\n" << p << "/" << (p + f) << " passed\n";
|
||||
return f > 0 ? 1 : 0;
|
||||
}
|
||||
95
editor/tests/step1979_test.cpp
Normal file
95
editor/tests/step1979_test.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
// Step 1979: CUDASymbolCatalog
|
||||
//
|
||||
// t1: catalog has cublasSgemm for cublas/compute.matrix
|
||||
// t2: catalog has thrust::sort for thrust/compute.sort
|
||||
// t3: cufft symbols present for compute.fft
|
||||
// t4: cudnn symbols present for compute.ml.inference
|
||||
// t5: total catalog has >= 18 symbols
|
||||
|
||||
#include "CUDASymbolCatalog.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace ws = whetstone;
|
||||
static int p = 0, f = 0;
|
||||
#define T(n) { std::cout << " " << #n << "... "; }
|
||||
#define P() { std::cout << "PASS\n"; ++p; }
|
||||
#define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; }
|
||||
#define C(c, m) if (!(c)) { F(m); return; }
|
||||
|
||||
void t1() {
|
||||
T(cublasSgemm_in_catalog);
|
||||
auto cat = ws::CUDASymbolCatalog::buildCatalog();
|
||||
auto syms = cat.get("cublas", "compute.matrix");
|
||||
C(syms.size() >= 5, "at least 5 cublas symbols");
|
||||
bool found = false;
|
||||
for (const auto& s : syms)
|
||||
if (s.functionName == "cublasSgemm") found = true;
|
||||
C(found, "cublasSgemm present");
|
||||
// Check signature contains cublasHandle_t
|
||||
for (const auto& s : syms) {
|
||||
if (s.functionName == "cublasSgemm") {
|
||||
C(s.signature.find("cublasHandle_t") != std::string::npos, "signature has handle");
|
||||
C(!s.caveats.empty(), "cublasSgemm has caveats");
|
||||
}
|
||||
}
|
||||
P();
|
||||
}
|
||||
|
||||
void t2() {
|
||||
T(thrust_sort_in_catalog);
|
||||
auto cat = ws::CUDASymbolCatalog::buildCatalog();
|
||||
auto syms = cat.get("thrust", "compute.sort");
|
||||
C(!syms.empty(), "thrust/compute.sort non-empty");
|
||||
bool found = false;
|
||||
for (const auto& s : syms)
|
||||
if (s.functionName == "thrust::sort") found = true;
|
||||
C(found, "thrust::sort present");
|
||||
// Also verify compute.parallel has thrust symbols
|
||||
auto par = cat.get("thrust", "compute.parallel");
|
||||
C(par.size() >= 4, "at least 4 thrust/compute.parallel symbols");
|
||||
P();
|
||||
}
|
||||
|
||||
void t3() {
|
||||
T(cufft_symbols_for_compute_fft);
|
||||
auto cat = ws::CUDASymbolCatalog::buildCatalog();
|
||||
auto syms = cat.get("cufft", "compute.fft");
|
||||
C(syms.size() >= 3, "at least 3 cufft symbols");
|
||||
bool hasPlan = false, hasExec = false;
|
||||
for (const auto& s : syms) {
|
||||
if (s.functionName == "cufftPlan1d") hasPlan = true;
|
||||
if (s.functionName == "cufftExecC2C") hasExec = true;
|
||||
}
|
||||
C(hasPlan, "cufftPlan1d present");
|
||||
C(hasExec, "cufftExecC2C present");
|
||||
P();
|
||||
}
|
||||
|
||||
void t4() {
|
||||
T(cudnn_symbols_for_ml_inference);
|
||||
auto cat = ws::CUDASymbolCatalog::buildCatalog();
|
||||
auto syms = cat.get("cudnn", "compute.ml.inference");
|
||||
C(syms.size() >= 5, "at least 5 cudnn symbols");
|
||||
bool hasConv = false, hasCreate = false;
|
||||
for (const auto& s : syms) {
|
||||
if (s.functionName == "cudnnConvolutionForward") hasConv = true;
|
||||
if (s.functionName == "cudnnCreate") hasCreate = true;
|
||||
}
|
||||
C(hasConv, "cudnnConvolutionForward present");
|
||||
C(hasCreate, "cudnnCreate present");
|
||||
P();
|
||||
}
|
||||
|
||||
void t5() {
|
||||
T(total_catalog_size_at_least_18);
|
||||
auto cat = ws::CUDASymbolCatalog::buildCatalog();
|
||||
C(cat.size() >= 18, "at least 18 total symbols, got " + std::to_string(cat.size()));
|
||||
P();
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::cout << "Step 1979: CUDASymbolCatalog\n";
|
||||
t1(); t2(); t3(); t4(); t5();
|
||||
std::cout << "\n" << p << "/" << (p + f) << " passed\n";
|
||||
return f > 0 ? 1 : 0;
|
||||
}
|
||||
95
editor/tests/step1980_test.cpp
Normal file
95
editor/tests/step1980_test.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
// Step 1980: ProjectStackDeclarator
|
||||
//
|
||||
// t1: declare and librariesForDomain returns qualifying libs
|
||||
// t2: library with score 0 not returned by librariesForDomain
|
||||
// t3: hasDomain checks operationDomains list
|
||||
// t4: empty declared set returns empty
|
||||
// t5: multiple qualifying libraries for one domain all returned
|
||||
|
||||
#include "ProjectStackDeclarator.h"
|
||||
#include "CUDALibraryProfile.h"
|
||||
#include "Sprint286IntegrationSummary.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace ws = whetstone;
|
||||
static int p = 0, f = 0;
|
||||
#define T(n) { std::cout << " " << #n << "... "; }
|
||||
#define P() { std::cout << "PASS\n"; ++p; }
|
||||
#define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; }
|
||||
#define C(c, m) if (!(c)) { F(m); return; }
|
||||
|
||||
void t1() {
|
||||
T(declare_and_librariesForDomain_returns_qualifying);
|
||||
auto ledger = ws::CUDALibraryProfile::buildLedger();
|
||||
ws::ProjectStackDeclarator decl;
|
||||
decl.projectId = "test";
|
||||
decl.declare("cublas");
|
||||
decl.declare("cufft");
|
||||
decl.declare("thrust");
|
||||
auto libs = decl.librariesForDomain("compute.matrix", ledger);
|
||||
C(libs.size() == 1, "1 qualifying lib for compute.matrix");
|
||||
C(libs[0] == "cublas", "cublas qualifies");
|
||||
auto fft_libs = decl.librariesForDomain("compute.fft", ledger);
|
||||
C(fft_libs.size() == 1, "1 qualifying lib for compute.fft");
|
||||
C(fft_libs[0] == "cufft", "cufft qualifies");
|
||||
P();
|
||||
}
|
||||
|
||||
void t2() {
|
||||
T(zero_score_library_not_returned);
|
||||
auto ledger = ws::CUDALibraryProfile::buildLedger();
|
||||
ws::ProjectStackDeclarator decl;
|
||||
decl.declare("cublas");
|
||||
decl.declare("cufft");
|
||||
// cublas/compute.fft = 0, cufft/compute.fft = 0.99
|
||||
auto libs = decl.librariesForDomain("compute.fft", ledger);
|
||||
C(libs.size() == 1, "only cufft qualifies");
|
||||
C(libs[0] == "cufft", "cufft is the only result");
|
||||
P();
|
||||
}
|
||||
|
||||
void t3() {
|
||||
T(hasDomain_checks_domains_list);
|
||||
ws::ProjectStackDeclarator decl;
|
||||
decl.addDomain("compute.matrix");
|
||||
decl.addDomain("serialization.json");
|
||||
C(decl.hasDomain("compute.matrix"), "compute.matrix present");
|
||||
C(decl.hasDomain("serialization.json"), "serialization.json present");
|
||||
C(!decl.hasDomain("compute.fft"), "compute.fft absent");
|
||||
P();
|
||||
}
|
||||
|
||||
void t4() {
|
||||
T(empty_declared_returns_empty);
|
||||
auto ledger = ws::CUDALibraryProfile::buildLedger();
|
||||
ws::ProjectStackDeclarator decl;
|
||||
auto libs = decl.librariesForDomain("compute.matrix", ledger);
|
||||
C(libs.empty(), "empty declared set -> empty result");
|
||||
P();
|
||||
}
|
||||
|
||||
void t5() {
|
||||
T(multiple_qualifying_libs_all_returned);
|
||||
auto ledger = ws::Sprint286IntegrationSummary::buildSeedLedger();
|
||||
ws::ProjectStackDeclarator decl;
|
||||
decl.declare("cublas");
|
||||
decl.declare("numpy");
|
||||
// Both cublas (0.99) and numpy (0.95) qualify for compute.matrix
|
||||
auto libs = decl.librariesForDomain("compute.matrix", ledger);
|
||||
C(libs.size() == 2, "both cublas and numpy qualify");
|
||||
bool hasCublas = false, hasNumpy = false;
|
||||
for (const auto& l : libs) {
|
||||
if (l == "cublas") hasCublas = true;
|
||||
if (l == "numpy") hasNumpy = true;
|
||||
}
|
||||
C(hasCublas, "cublas present");
|
||||
C(hasNumpy, "numpy present");
|
||||
P();
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::cout << "Step 1980: ProjectStackDeclarator\n";
|
||||
t1(); t2(); t3(); t4(); t5();
|
||||
std::cout << "\n" << p << "/" << (p + f) << " passed\n";
|
||||
return f > 0 ? 1 : 0;
|
||||
}
|
||||
99
editor/tests/step1981_test.cpp
Normal file
99
editor/tests/step1981_test.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
// Step 1981: ProofPipelineRunner
|
||||
//
|
||||
// t1: run() on "GPU matrix multiply. JSON result serialization." -> 2 contracts
|
||||
// t2: first contract selects cublas for compute.matrix
|
||||
// t3: second contract selects nlohmann_json for serialization.json
|
||||
// t4: run() skips unknown-domain sentences
|
||||
// t5: empty spec produces no contracts
|
||||
|
||||
#include "ProofPipelineRunner.h"
|
||||
#include "CUDALibraryProfile.h"
|
||||
#include "CUDASymbolCatalog.h"
|
||||
#include "Sprint286IntegrationSummary.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace ws = whetstone;
|
||||
static int p = 0, f = 0;
|
||||
#define T(n) { std::cout << " " << #n << "... "; }
|
||||
#define P() { std::cout << "PASS\n"; ++p; }
|
||||
#define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; }
|
||||
#define C(c, m) if (!(c)) { F(m); return; }
|
||||
|
||||
static ws::ProofPipelineRunner makeCUDARunner() {
|
||||
auto ledger = ws::CUDALibraryProfile::buildLedger();
|
||||
// Add nlohmann_json for JSON tasks
|
||||
ledger.set({"nlohmann_json", "serialization.json", 0.92f,
|
||||
{"nlohmann::json::dump()", "nlohmann::json::parse()"}, {},
|
||||
false, "2026-03-02", "benchmark"});
|
||||
auto catalog = ws::CUDASymbolCatalog::buildCatalog();
|
||||
ws::ProjectStackDeclarator decl;
|
||||
decl.declare("cublas"); decl.declare("cufft");
|
||||
decl.declare("thrust"); decl.declare("cudnn");
|
||||
decl.declare("nlohmann_json");
|
||||
return ws::ProofPipelineRunner(std::move(decl),
|
||||
std::move(ledger),
|
||||
std::move(catalog));
|
||||
}
|
||||
|
||||
void t1() {
|
||||
T(run_cuda_json_spec_produces_2_contracts);
|
||||
auto runner = makeCUDARunner();
|
||||
auto contracts = runner.run("GPU matrix multiply. JSON result serialization.");
|
||||
C(contracts.size() == 2, "2 enriched contracts, got " + std::to_string(contracts.size()));
|
||||
for (const auto& c : contracts) {
|
||||
C(c.isEnriched(), "each contract is enriched");
|
||||
}
|
||||
P();
|
||||
}
|
||||
|
||||
void t2() {
|
||||
T(cublas_selected_for_compute_matrix);
|
||||
auto runner = makeCUDARunner();
|
||||
auto contracts = runner.run("GPU matrix multiply. JSON result serialization.");
|
||||
bool found = false;
|
||||
for (const auto& c : contracts) {
|
||||
if (c.operationDomain == "compute.matrix" && c.selectedLibrary == "cublas")
|
||||
found = true;
|
||||
}
|
||||
C(found, "cublas/compute.matrix contract present");
|
||||
P();
|
||||
}
|
||||
|
||||
void t3() {
|
||||
T(nlohmann_selected_for_serialization_json);
|
||||
auto runner = makeCUDARunner();
|
||||
auto contracts = runner.run("GPU matrix multiply. JSON result serialization.");
|
||||
bool found = false;
|
||||
for (const auto& c : contracts) {
|
||||
if (c.operationDomain == "serialization.json" && c.selectedLibrary == "nlohmann_json")
|
||||
found = true;
|
||||
}
|
||||
C(found, "nlohmann_json/serialization.json contract present");
|
||||
P();
|
||||
}
|
||||
|
||||
void t4() {
|
||||
T(unknown_domain_sentences_skipped);
|
||||
auto runner = makeCUDARunner();
|
||||
// "xyzzy frobnicate" has no known domain
|
||||
auto contracts = runner.run("GPU matrix multiply. xyzzy frobnicate. JSON result serialization.");
|
||||
C(contracts.size() == 2, "still 2 contracts (unknown sentence skipped)");
|
||||
P();
|
||||
}
|
||||
|
||||
void t5() {
|
||||
T(empty_spec_produces_no_contracts);
|
||||
auto runner = makeCUDARunner();
|
||||
auto contracts = runner.run("");
|
||||
C(contracts.empty(), "no contracts for empty spec");
|
||||
auto contracts2 = runner.run("...");
|
||||
C(contracts2.empty(), "no contracts for dots-only spec");
|
||||
P();
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::cout << "Step 1981: ProofPipelineRunner\n";
|
||||
t1(); t2(); t3(); t4(); t5();
|
||||
std::cout << "\n" << p << "/" << (p + f) << " passed\n";
|
||||
return f > 0 ? 1 : 0;
|
||||
}
|
||||
77
editor/tests/step1982_test.cpp
Normal file
77
editor/tests/step1982_test.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
// Step 1982: Sprint 290 Integration — CUDA End-to-End Proof
|
||||
//
|
||||
// t1: runProof() produces >= 2 enriched contracts
|
||||
// t2: verifyGPUMatrixMultiply passes (cublas selected)
|
||||
// t3: verifyJSONSerialization passes (nlohmann_json selected)
|
||||
// t4: GPU matrix multiply contract has non-empty preferredAPIs
|
||||
// t5: Sprint290IntegrationSummary metadata correct
|
||||
|
||||
#include "Sprint290IntegrationSummary.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace ws = whetstone;
|
||||
static int p = 0, f = 0;
|
||||
#define T(n) { std::cout << " " << #n << "... "; }
|
||||
#define P() { std::cout << "PASS\n"; ++p; }
|
||||
#define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; }
|
||||
#define C(c, m) if (!(c)) { F(m); return; }
|
||||
|
||||
void t1() {
|
||||
T(run_proof_produces_enriched_contracts);
|
||||
auto contracts = ws::Sprint290IntegrationSummary::runProof();
|
||||
C(contracts.size() >= 2, "at least 2 contracts");
|
||||
for (const auto& c : contracts) {
|
||||
C(c.isEnriched(), "all contracts enriched");
|
||||
}
|
||||
P();
|
||||
}
|
||||
|
||||
void t2() {
|
||||
T(verify_gpu_matrix_multiply_passes);
|
||||
C(ws::Sprint290IntegrationSummary::verifyGPUMatrixMultiply(),
|
||||
"verifyGPUMatrixMultiply");
|
||||
P();
|
||||
}
|
||||
|
||||
void t3() {
|
||||
T(verify_json_serialization_passes);
|
||||
C(ws::Sprint290IntegrationSummary::verifyJSONSerialization(),
|
||||
"verifyJSONSerialization");
|
||||
P();
|
||||
}
|
||||
|
||||
void t4() {
|
||||
T(gpu_matrix_contract_has_preferred_apis);
|
||||
auto contracts = ws::Sprint290IntegrationSummary::runProof();
|
||||
bool found = false;
|
||||
for (const auto& c : contracts) {
|
||||
if (c.operationDomain == "compute.matrix" && c.selectedLibrary == "cublas") {
|
||||
C(!c.preferredAPIs.empty(), "preferredAPIs non-empty for cublas");
|
||||
C(c.capabilityScore == 0.99f, "capabilityScore = 0.99");
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
C(found, "cublas/compute.matrix contract found");
|
||||
P();
|
||||
}
|
||||
|
||||
void t5() {
|
||||
T(sprint290_metadata_correct);
|
||||
ws::Sprint290IntegrationSummary s;
|
||||
C(s.stepsCompleted == 5, "5 steps");
|
||||
C(s.success, "success");
|
||||
C(s.sprintName() == "Sprint 290: CUDA End-to-End Proof", "sprintName");
|
||||
// Also verify combined ledger has CUDA + nlohmann entries
|
||||
auto ledger = ws::Sprint290IntegrationSummary::buildCombinedLedger();
|
||||
C(ledger.score("cublas", "compute.matrix") == 0.99f, "cublas/compute.matrix in combined");
|
||||
C(ledger.score("nlohmann_json", "serialization.json") == 0.92f, "nlohmann in combined");
|
||||
C(ledger.score("cufft", "compute.fft") == 0.99f, "cufft/compute.fft in combined");
|
||||
P();
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::cout << "Step 1982: Sprint 290 Integration — CUDA End-to-End Proof\n";
|
||||
t1(); t2(); t3(); t4(); t5();
|
||||
std::cout << "\n" << p << "/" << (p + f) << " passed\n";
|
||||
return f > 0 ? 1 : 0;
|
||||
}
|
||||
Reference in New Issue
Block a user