Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/scripts/regression-dynamic.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ parameters = { channels = 4, check_interval = 2, tolerance = 2 }
[[dynamic_query]]
iterations = 10
elements_per_dpu = [16384]
parameters = { columns = 4, projections = 4, batches_per_query = 5, query_ops = 6 }
parameters = { columns = 4, batches_per_query = 5, query_ops = 6 }
2 changes: 1 addition & 1 deletion benchmarks/dynamic-benchmarks/benchmark.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ variants = [
"polymerpim-pipeline",
"simplepim",
]
parameters = { columns = 4, projections = 4, batches_per_query = 5, query_ops = 6 }
parameters = { columns = 4, batches_per_query = 5, query_ops = 6 }
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const uint32_t check_correctness = 0;
const uint32_t load_ref = 0;
const uint32_t seed = 1;
const uint32_t columns = 4;
const uint32_t projections = 4;
const uint32_t batches_per_query = 5;
const uint32_t query_ops = 6;
const char* query_trace = "../../dynamic_query.csv";
Expand Down
78 changes: 28 additions & 50 deletions benchmarks/dynamic-benchmarks/polymerpim/dynamic_query/run.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,12 @@ static std::vector<QueryPlan> load_queries(const char* path) {
return queries;
}

static auto project(const QueryPlan& plan, uint32_t projection,
static auto project(const QueryPlan& plan,
const std::vector<DPUVector<T>>& input) {
using Expression = decltype(input[0] + (T)0);
Expression value = input[projection % columns];
Expression value = input[0];
for (const QueryStep& step : plan) {
const auto& operand = input[(step.column + projection) % columns];
const auto& operand = input[step.column % columns];
switch (step.op) {
case QueryOp::ADD:
value = value + operand;
Expand All @@ -101,16 +101,13 @@ static auto project(const QueryPlan& plan, uint32_t projection,
break;
}
}
const auto& lhs = input[projection % columns];
const auto& rhs = input[(projection + 1) % columns];
return value * (lhs < rhs);
return value * (input[0] < input[1]);
}

static T project_cpu(const QueryPlan& plan, uint32_t projection,
uint64_t index) {
T value = column_value(index, projection % columns);
static T project_cpu(const QueryPlan& plan, uint64_t index) {
T value = column_value(index, 0);
for (const QueryStep& step : plan) {
T operand = column_value(index, (step.column + projection) % columns);
T operand = column_value(index, step.column % columns);
switch (step.op) {
case QueryOp::ADD:
value += operand;
Expand All @@ -126,17 +123,15 @@ static T project_cpu(const QueryPlan& plan, uint32_t projection,
break;
}
}
T lhs = column_value(index, projection % columns);
T rhs = column_value(index, (projection + 1) % columns);
return lhs < rhs ? value : 0;
return column_value(index, 0) < column_value(index, 1) ? value : 0;
}

static QueryResult expected_max(const QueryPlan& plan, uint32_t projection) {
static QueryResult expected_max(const QueryPlan& plan) {
T result = std::numeric_limits<T>::lowest();
const uint64_t period = std::min<uint64_t>(N, 251);
#pragma omp parallel for reduction(max : result)
for (uint64_t i = 0; i < period; ++i) {
result = std::max(result, project_cpu(plan, projection, i));
result = std::max(result, project_cpu(plan, i));
}
return (QueryResult)result;
}
Expand All @@ -147,12 +142,11 @@ int main() {
std::cerr << "dynamic_query requires warmup=0" << std::endl;
return 2;
}
if (columns < 2 || projections == 0 || projections > columns ||
batches_per_query == 0 || iterations == 0 || query_ops == 0) {
std::cerr
<< "dynamic_query requires columns>=2, 1<=projections<=columns, "
"batches_per_query>0, iterations>0, and query_ops>0"
<< std::endl;
if (columns < 2 || batches_per_query == 0 || iterations == 0 ||
query_ops == 0) {
std::cerr << "dynamic_query requires columns>=2, batches_per_query>0, "
"iterations>0, and query_ops>0"
<< std::endl;
return 2;
}

Expand Down Expand Up @@ -210,37 +204,26 @@ int main() {
const QueryPlan& plan = queries[query];
std::vector<QueryResult> checked_results;
if (check_correctness) {
checked_results.reserve(batches_per_query * projections);
checked_results.reserve(batches_per_query);
}
bench_start(&timer, 0);

for (uint32_t batch = 0; batch < batches_per_query; ++batch) {
bench_start(&batch_timer, 0);
bench_stage_begin(&stages, BENCH_STAGE_KERNEL);
std::vector<DpuFuture<T>> pending;
pending.reserve(projections);
for (uint32_t projection = 0; projection < projections; ++projection) {
pending.push_back(maximum(project(plan, projection, input)));
}
DpuFuture<T> pending = maximum(project(plan, input));
sync();
bench_stage_end(&stages);

bench_stage_begin(&stages, BENCH_STAGE_READ);
std::vector<QueryResult> results;
results.reserve(projections);
for (auto& future : pending) {
results.push_back(future.get());
}
QueryResult result = pending.get();
bench_stage_end(&stages);

if (check_correctness) {
checked_results.insert(checked_results.end(), results.begin(),
results.end());
checked_results.push_back(result);
}

for (QueryResult result : results) {
checksum = checksum * UINT64_C(1099511628211) ^ (uint64_t)result;
}
checksum = checksum * UINT64_C(1099511628211) ^ (uint64_t)result;

bench_stop(&batch_timer, 0);
bench_stats_update(batch == 0 ? &first_batch_stats : &reuse_batch_stats,
Expand All @@ -251,17 +234,13 @@ int main() {
bench_stats_update(&stats, timer.time[0]);

if (check_correctness) {
for (uint32_t projection = 0; projection < projections; ++projection) {
QueryResult expected = expected_max(plan, projection);
for (uint32_t batch = 0; batch < batches_per_query; ++batch) {
QueryResult actual =
checked_results[batch * projections + projection];
if (actual != expected) {
std::cerr << "Mismatch in query " << query << ", batch " << batch
<< ", projection " << projection << ": got " << actual
<< ", expected " << expected << std::endl;
return 1;
}
QueryResult expected = expected_max(plan);
for (uint32_t batch = 0; batch < batches_per_query; ++batch) {
if (checked_results[batch] != expected) {
std::cerr << "Mismatch in query " << query << ", batch " << batch
<< ": got " << checked_results[batch] << ", expected "
<< expected << std::endl;
return 1;
}
}
}
Expand Down Expand Up @@ -291,8 +270,7 @@ int main() {
std::cout << "dynamic_query: queries=" << iterations
<< " trace_queries=" << queries.size()
<< " batches_per_query=" << batches_per_query
<< " query_ops=" << query_ops << " projections=" << projections
<< " checksum=" << checksum
<< " query_ops=" << query_ops << " checksum=" << checksum
<< " compute_launches=" << runtime_stats.compute_launches
<< " vertical_fusions=" << runtime_stats.vertical_fusions
<< " horizontal_fusions=" << runtime_stats.horizontal_fusions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ const uint32_t check_correctness = 0;
const uint32_t load_ref = 0;
const uint32_t seed = 1;
const uint32_t columns = QUERY_COLUMNS;
const uint32_t projections = 4;
const uint32_t batches_per_query = 5;
const uint32_t query_ops = 6;
const char* query_trace = "../../dynamic_query.csv";
Expand Down
65 changes: 25 additions & 40 deletions benchmarks/dynamic-benchmarks/simplepim/dynamic_query/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,10 @@ static query_plan_t* load_queries(uint32_t* count) {
return queries;
}

static T project_cpu(const query_plan_t* plan, uint32_t projection,
uint64_t index) {
T value = column_value(index, projection % columns);
static T project_cpu(const query_plan_t* plan, uint64_t index) {
T value = column_value(index, 0);
for (uint32_t i = 0; i < plan->count; ++i) {
T operand =
column_value(index, (plan->steps[i].column + projection) % columns);
T operand = column_value(index, plan->steps[i].column % columns);
switch (plan->steps[i].op) {
case QUERY_ADD:
value += operand;
Expand All @@ -109,18 +107,15 @@ static T project_cpu(const query_plan_t* plan, uint32_t projection,
break;
}
}
return column_value(index, projection % columns) <
column_value(index, (projection + 1) % columns)
? value
: 0;
return column_value(index, 0) < column_value(index, 1) ? value : 0;
}

static T expected_max(const query_plan_t* plan, uint32_t projection) {
static T expected_max(const query_plan_t* plan) {
T result = INT32_MIN;
uint64_t period = nr_elements < 251 ? nr_elements : 251;
#pragma omp parallel for reduction(max : result)
for (uint64_t i = 0; i < period; ++i) {
T value = project_cpu(plan, projection, i);
T value = project_cpu(plan, i);
if (value > result) {
result = value;
}
Expand All @@ -142,8 +137,8 @@ int main(void) {
fprintf(stderr, "dynamic_query requires warmup=0\n");
return 2;
}
if (columns != QUERY_COLUMNS || projections == 0 || projections > columns ||
batches_per_query == 0 || query_ops == 0 || iterations == 0) {
if (columns != QUERY_COLUMNS || batches_per_query == 0 || query_ops == 0 ||
iterations == 0) {
fprintf(stderr, "invalid dynamic_query parameters\n");
return 2;
}
Expand Down Expand Up @@ -200,31 +195,24 @@ int main(void) {
char functions[64];
snprintf(functions, sizeof(functions), "query_%03u_funcs", query);
handle_t* handle = NULL;
T checked_results[batches_per_query * projections];
T checked_results[batches_per_query];
bench_start(&query_timer, 0);
for (uint32_t batch = 0; batch < batches_per_query; ++batch) {
bench_start(&batch_timer, 0);
bench_stage_begin(&stages, BENCH_STAGE_KERNEL);
if (batch == 0) {
handle = create_handle(functions, REDUCE);
}
T results[QUERY_COLUMNS];
for (uint32_t projection = 0; projection < projections; ++projection) {
T* result = table_gen_red("query_rows", "query_result", sizeof(T), 1,
handle, management, projection);
results[projection] = result[0];
free(result);
}
T* result = table_gen_red("query_rows", "query_result", sizeof(T), 1,
handle, management, 0);
T value = result[0];
free(result);
bench_stage_end(&stages);

if (check_correctness) {
memcpy(&checked_results[batch * projections], results,
projections * sizeof(T));
}
for (uint32_t projection = 0; projection < projections; ++projection) {
checksum =
checksum * UINT64_C(1099511628211) ^ (uint64_t)results[projection];
checked_results[batch] = value;
}
checksum = checksum * UINT64_C(1099511628211) ^ (uint64_t)value;
bench_stop(&batch_timer, 0);
bench_stats_update(batch == 0 ? &first_stats : &reuse_stats,
batch_timer.time[0]);
Expand All @@ -233,17 +221,14 @@ int main(void) {
bench_stats_update(&stats, query_timer.time[0]);

if (check_correctness) {
for (uint32_t projection = 0; projection < projections; ++projection) {
T expected = expected_max(&queries[query], projection);
for (uint32_t batch = 0; batch < batches_per_query; ++batch) {
T actual = checked_results[batch * projections + projection];
if (actual != expected) {
fprintf(stderr,
"Mismatch in query %u, batch %u, projection %u: got %d, "
"expected %d\n",
query, batch, projection, actual, expected);
return 1;
}
T expected = expected_max(&queries[query]);
for (uint32_t batch = 0; batch < batches_per_query; ++batch) {
if (checked_results[batch] != expected) {
fprintf(stderr,
"Mismatch in query %u, batch %u: got %d, "
"expected %d\n",
query, batch, checked_results[batch], expected);
return 1;
}
}
}
Expand All @@ -268,8 +253,8 @@ int main(void) {
reuse_stats.count ? reuse_stats.mean / 1000.0 : 0.0);
printf(
"dynamic_query: queries=%u trace_queries=%u batches_per_query=%u "
"query_ops=%u projections=%u checksum=%llu\n",
iterations, trace_queries, batches_per_query, query_ops, projections,
"query_ops=%u checksum=%llu\n",
iterations, trace_queries, batches_per_query, query_ops,
(unsigned long long)checksum);
if (check_correctness) {
printf("All results match after %u queries.\n", iterations);
Expand Down
Loading