Skip to content

Commit

Permalink
working on task definitions for identity example
Browse files Browse the repository at this point in the history
  • Loading branch information
ngc92 committed Jan 20, 2025
1 parent 957b265 commit e5de58f
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 56 deletions.
65 changes: 27 additions & 38 deletions examples/identity_cuda/eval.cu
Original file line number Diff line number Diff line change
Expand Up @@ -6,61 +6,50 @@
#include <algorithm>
#include <memory>

#include "utils.h"
#include "reference.cuh"
#include "submission.cuh"

// forward declaration for user submission
output_t custom_kernel(input_t data);

#define WARMUP_RUNS 10
#define TIMED_RUNS 100

struct Closer {
void operator()(std::FILE* file) {
std::fclose(file);
}
};
namespace {
struct Closer {
void operator()(std::FILE* file) {
std::fclose(file);
}
};

struct PopcornOutput {
template<class... Args>
void printf(Args&&... args) {
::fprintf(File.get(), std::forward<Args>(args)...);
}
struct PopcornOutput {
template<class... Args>
void printf(Args&&... args) {
::fprintf(File.get(), std::forward<Args>(args)...);
}

void log(const char* key, const char* value) {
printf("%s: %s\n", key, value);
}
void log(const char* key, const char* value) {
printf("%s: %s\n", key, value);
}

template<class T>
void log(const char* key, T&& value) {
log(key, std::to_string(value).c_str());
}
template<class T>
void log(const char* key, T&& value) {
log(key, std::to_string(value).c_str());
}

std::unique_ptr<std::FILE, Closer> File;
};

// checks that a CUDA API call returned successfully, otherwise prints an error message and exits.
static void cuda_check(cudaError_t status, const char* expr, const char* file, int line, const char* function)
{
if(status != cudaSuccess) {
std::cerr << "CUDA error (" << (int)status << ") while evaluating expression "
<< expr << " at "
<< file << '('
<< line << ") in `"
<< function << "`: "
<< cudaGetErrorString(status) << std::endl;
std::exit(110);
}
std::unique_ptr<std::FILE, Closer> File;
};
}

#define cuda_check(expr) cuda_check(expr, #expr, __FILE__, __LINE__, __FUNCTION__)

void measure_runtime(PopcornOutput& logger, std::mt19937& rng) {
static void measure_runtime(PopcornOutput& logger, std::mt19937& rng) {
std::cout << "warming up..." << std::endl;

{
auto warmup_data = generate_input(rng());
for (int i = 0; i < WARMUP_RUNS; i++) {
// discard result; this is just warmup, we don't care what it returns
(void)custom_kernel(warmup_data);
cuda_check(cudaDeviceSynchronize());
CUDA_CHECK(cudaDeviceSynchronize());
}
}

Expand All @@ -77,7 +66,7 @@ void measure_runtime(PopcornOutput& logger, std::mt19937& rng) {
// move data into custom_kernel, so that if custom_kernel takes large std::vectors or similar by value,
// we're not measuring the copy overhead.
auto submission_output = custom_kernel(std::move(data));
cuda_check(cudaDeviceSynchronize());
CUDA_CHECK(cudaDeviceSynchronize());
auto end = std::chrono::high_resolution_clock::now();

durations.push_back(std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count());
Expand Down
13 changes: 4 additions & 9 deletions examples/identity_cuda/reference.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,9 @@
#include <random>
#include <iostream>

#define N_SIZES 10
const int Ns[N_SIZES] = {128, 256, 512, 1024, 2048,
4096, 8192, 16384, 32768, 65536};
#include "task.h"

using input_t = std::array<std::vector<float>, N_SIZES>;
using output_t = input_t;

input_t generate_input(int seed) {
static input_t generate_input(int seed) {
std::mt19937 rng(seed);
input_t data;

Expand All @@ -33,11 +28,11 @@ input_t generate_input(int seed) {
}

// The identity kernel
output_t ref_kernel(input_t data) {
static output_t ref_kernel(input_t data) {
return (output_t) data;
}

bool check_implementation(output_t out, output_t ref, float epsilon = 1e-5) {
static bool check_implementation(output_t out, output_t ref, float epsilon = 1e-5) {
// input_t data = generate_input();
// output_t reference_out = reference(data);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <array>
#include <vector>
#include "reference.cuh"
#include "task.h"
#include "utils.h"

__global__ void copy_kernel(float *input, float *output, int N)
{
Expand All @@ -22,23 +23,23 @@ output_t custom_kernel(input_t data)

// Allocate device memory
float *d_input, *d_output;
cudaMalloc(&d_input, N * sizeof(float));
cudaMalloc(&d_output, N * sizeof(float));
CUDA_CHECK(cudaMalloc(&d_input, N * sizeof(float)));
CUDA_CHECK(cudaMalloc(&d_output, N * sizeof(float)));

// Copy input to device
cudaMemcpy(d_input, data[i].data(), N * sizeof(float), cudaMemcpyHostToDevice);
CUDA_CHECK(cudaMemcpy(d_input, data[i].data(), N * sizeof(float), cudaMemcpyHostToDevice));

// Launch kernel
int blockSize = 256;
int numBlocks = (N + blockSize - 1) / blockSize;
copy_kernel<<<numBlocks, blockSize>>>(d_input, d_output, N);

// Copy result back to host
cudaMemcpy(result[i].data(), d_output, N * sizeof(float), cudaMemcpyDeviceToHost);
CUDA_CHECK(cudaMemcpy(result[i].data(), d_output, N * sizeof(float), cudaMemcpyDeviceToHost));

// Free device memory
cudaFree(d_input);
cudaFree(d_output);
CUDA_CHECK(cudaFree(d_input));
CUDA_CHECK(cudaFree(d_output));
}

return result;
Expand Down
14 changes: 14 additions & 0 deletions examples/identity_cuda/task.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef __TASK_H__
#define __TASK_H__

#include <vector>
#include <array>

#define N_SIZES 10
const int Ns[N_SIZES] = {128, 256, 512, 1024, 2048,
4096, 8192, 16384, 32768, 65536};

using input_t = std::array<std::vector<float>, N_SIZES>;
using output_t = input_t;

#endif
9 changes: 7 additions & 2 deletions examples/identity_cuda/task.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,21 @@
# these files will be baked into the json object, so that they are available during testing
files:
- {"name": "eval.cu", "source": "eval.cu"}
- {"name": "task.h", "source": "task.h"}
- {"name": "utils.h", "source": "utils.h"}
- {"name": "reference.cuh", "source": "reference.cuh"}
- {"name": "submission.cuh", "source": "@SUBMISSION@"}
- {"name": "submission.cu", "source": "@SUBMISSION@"}

# task language, depending on this we do get different keys in runner
lang: "cu"

description:
A simple test task

# Config object
config:
# task provided source files to compile
sources: ["eval.cu"]
sources: ["eval.cu", "submission.cu"]

# additional include directories
include_dirs: []
24 changes: 24 additions & 0 deletions examples/identity_cuda/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef POPCORN_UTILS_H
#define POPCORN_UTILS_H

#include <iostream>

// checks that a CUDA API call returned successfully, otherwise prints an error message and exits.
static inline void cuda_check_(cudaError_t status, const char* expr, const char* file, int line, const char* function)
{
if(status != cudaSuccess) {
std::cerr << "CUDA error (" << (int)status << ") while evaluating expression "
<< expr << " at "
<< file << '('
<< line << ") in `"
<< function << "`: "
<< cudaGetErrorString(status) << std::endl;
std::exit(110);
}
}

// Convenience macro, automatically logs expression, file, line, and function name
// of the error.
#define CUDA_CHECK(expr) cuda_check_(expr, #expr, __FILE__, __LINE__, __FUNCTION__)

#endif
3 changes: 3 additions & 0 deletions src/discord-cluster-manager/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class LeaderboardTask:
Attributes:
lang: Programming language of this task. Specifies the type of
the `data` attribute.
description: A description of the task.
TODO use for a sticky message for the LBs channel
files: Dictionary containing a mapping of file names to file
contents. Contents '@SUBMISSION@' get replaced with the
submitted file before sending to the runner.
Expand All @@ -41,6 +43,7 @@ class LeaderboardTask:
lang: Language
files: dict[str, str]
config: CudaTaskData | PythonTaskData
description: str = ''
libraries: list[str] = dataclasses.field(default_factory=list)

@staticmethod
Expand Down

0 comments on commit e5de58f

Please sign in to comment.