Skip to content

Commit

Permalink
update: 优化 summary,完成 22 题
Browse files Browse the repository at this point in the history
Signed-off-by: YdrMaster <[email protected]>
  • Loading branch information
YdrMaster committed Jul 13, 2024
1 parent e1230ff commit 192b569
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 37 deletions.
68 changes: 68 additions & 0 deletions exercises/21_template_const/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include "../exercise.h"

// READ: 模板非类型实参 <https://zh.cppreference.com/w/cpp/language/template_parameters#%E6%A8%A1%E6%9D%BF%E9%9D%9E%E7%B1%BB%E5%9E%8B%E5%AE%9E%E5%8F%82>

template<unsigned int N, class T>
struct Tensor {
unsigned int shape[N];
T *data;

Tensor(unsigned int const shape_[N]) {
unsigned int size = 1;
// TODO: 填入正确的 shape 并计算 size
data = new T[size];
std::memset(data, 0, size * sizeof(T));
}
~Tensor() {
delete[] data;
}

// 为了保持简单,禁止复制和移动
Tensor(Tensor const &) = delete;
Tensor(Tensor &&) noexcept = delete;

T &operator[](unsigned int const indices[N]) {
return data[data_index(indices)];
}
T const &operator[](unsigned int const indices[N]) const {
return data[data_index(indices)];
}

private:
unsigned int data_index(unsigned int const indices[N]) const {
unsigned int index = 0;
for (unsigned int i = 0; i < N; ++i) {
ASSERT(indices[i] < shape[i]);
// TODO: 计算 index
}
}
};

// ---- 不要修改以下代码 ----
int main(int argc, char **argv) {
{
unsigned int shape[]{2, 3, 4, 5};
auto tensor = Tensor<4, int>(shape);

unsigned int i0[]{0, 0, 0, 0};
tensor[i0] = 1;
ASSERT(tensor[i0] == 1, "tensor[i0] should be 1");

unsigned int i1[]{1, 2, 3, 4};
tensor[i0] = 2;
ASSERT(tensor[i0] == 2, "tensor[i1] should be 2");
}
{
unsigned int shape[]{7, 8, 128};
auto tensor = Tensor<3, float>(shape);

unsigned int i0[]{0, 0, 0};
tensor[i0] = 1.f;
ASSERT(tensor[i0] == 1.f, "tensor[i0] should be 1");

unsigned int i1[]{3, 4, 99};
tensor[i0] = 2.f;
ASSERT(tensor[i0] == 2.f, "tensor[i1] should be 2");
}
return 0;
}
28 changes: 28 additions & 0 deletions exercises/22_std_array/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "../exercise.h"
#include <array>
#include <cstring>

// READ: std::array <https://zh.cppreference.com/w/cpp/container/array>

// TODO: 将下列 `?` 替换为正确的代码
int main(int argc, char **argv) {
{
std::array<int, 5> arr{{1, 2, 3, 4, 5}};
ASSERT(arr.size() == ?, "Fill in the correct value.");
ASSERT(sizeof(arr) == ?, "Fill in the correct value.");
int ans[]{1, 2, 3, 4, 5};
ASSERT(std::memcmp(arr.?, ans, ?) == 0, "Fill in the correct values.");
}
{
std::array<double, 8> arr;
ASSERT(arr.size() == ?, "Fill in the correct value.");
ASSERT(sizeof(arr) == ?, "Fill in the correct value.");
}
{
std::array<char, 21> arr{"Hello, InfiniTensor!"};
ASSERT(arr.size() == ?, "Fill in the correct value.");
ASSERT(sizeof(arr) == ?, "Fill in the correct value.");
ASSERT(std::strcmp(arr.?, "Hello, InfiniTensor!") == 0, "Fill in the correct value.");
}
return 0;
}
8 changes: 7 additions & 1 deletion exercises/xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,10 @@ target("exercise19")
target("exercise20")
add_files("20_class_template/main.cpp")

-- TODO: array; vector; deque; map; forward_list; transform; accumulate; fs; thread; mutex;
target("exercise21")
add_files("21_template_const/main.cpp")

target("exercise22")
add_files("22_std_array/main.cpp")

-- TODO: vector; vector<bool>; deque; map; forward_list; string; transform; accumulate; fs; thread; mutex;
2 changes: 1 addition & 1 deletion learn/learn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ int main(int argc, char **argv) {
if (1 != std::sscanf(argv[1], "%d", &num)) {
std::cerr << "Invalid exercise number: " << argv[1] << std::endl;
};
test_exercise(num, nullptr);
Log{Console{}} << num;
return EXIT_SUCCESS;
}
36 changes: 14 additions & 22 deletions learn/summary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,36 @@
#include <cstring>
#include <iomanip>
#include <iostream>
#include <numeric>
#include <sstream>
#include <thread>
#include <vector>

constexpr auto MAX_EXERCISE = 20;
constexpr auto MAX_EXERCISE = 22;

int main(int argc, char **argv) {
if (argc == 1) {
std::vector<bool> result(MAX_EXERCISE + 1, false);
auto success = 0;
Log log{Console{}};
for (auto i = 0; i <= MAX_EXERCISE; ++i) {
if (test_exercise(i, nullptr)) {
result[i] = true;
++success;
}
log << i;
}

std::cout << success << "/" << MAX_EXERCISE + 1 << " [";
for (auto b : result) {
std::cout << std::accumulate(log.result.begin(), log.result.end(), 0, std::plus{}) << '/' << MAX_EXERCISE + 1 << " [";
for (auto b : log.result) {
std::cout << (b ? "\x1b[32m#\x1b[0m" : "\x1b[31mX\x1b[0m");
}
std::cout << ']' << std::endl;
return EXIT_SUCCESS;
}
if (argc == 2 && std::strcmp(argv[1], "--simple") == 0) {
auto time = std::chrono::system_clock::now();
auto time_ = std::chrono::system_clock::to_time_t(time);
std::stringstream ss;
ss << std::put_time(std::localtime(&time_), "%Y-%m-%d-%H-%M-%S") << ".log";
auto log_file = ss.str();

auto success = 0;
Log log{Null{}};
std::vector<std::thread> threads;
for (auto i = 0; i <= MAX_EXERCISE; ++i) {
if (test_exercise(i, log_file.c_str())) {
++success;
}
threads.emplace_back([&log, i]() { log << i; });
}

std::cout << success << "/" << MAX_EXERCISE + 1 << std::endl;
for (auto i = 0; i <= MAX_EXERCISE; ++i) {
threads[i].join();
}
std::cout << std::accumulate(log.result.begin(), log.result.end(), 0, std::plus{}) << '/' << MAX_EXERCISE + 1 << std::endl;
return EXIT_SUCCESS;
}
std::cerr << "Usage: xmake run summary [--simple]" << std::endl;
Expand Down
40 changes: 28 additions & 12 deletions learn/test.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <cstdlib>
#include "test.h"
#include <cstdlib>
#include <filesystem>
#include <fstream>
#include <iostream>
Expand All @@ -21,26 +22,41 @@ static int process_run(const char *cmd, const char *proj, const char *log) {
return std::system(command.c_str());
}

static bool test_exercise(std::ostream &os, int n, const char *log) {
static bool test_exercise(int n, std::ostream &os, const char *log) {
char str[] = "exerciseXX";
std::sprintf(str, "exercise%02d", n);

os << "\x1b[34m" << str << " testing" << "\x1b[0m" << std::endl
<< "==================" << std::endl
<< std::endl;
<< "==================" << std::endl;
auto pass = process_run("", str, log) == EXIT_SUCCESS && process_run("run", str, log) == EXIT_SUCCESS;
os << "=================" << std::endl
<< "\x1b[" << (pass ? 32 : 31) << 'm' << str << (pass ? " passed" : " failed") << "\x1b[0m" << std::endl;
<< "\x1b[" << (pass ? 32 : 31) << 'm' << str << (pass ? " passed" : " failed") << "\x1b[0m" << std::endl
<< std::endl;
return pass;
}

bool test_exercise(int n, const char *log) {
if (log) {
const auto log_ = fs::absolute(fs::path(XMAKE) / "log" / log);
const auto log__ = log_.string();
auto file = std::fstream(log_, std::ios::out | std::ios::app);
return test_exercise(file, n, log__.c_str());
Log &Log::operator<<(unsigned int n) {
namespace fs = std::filesystem;
bool pass;
if (std::holds_alternative<Console>(this->dst)) {
pass = test_exercise(n, std::cout, nullptr);
} else if (std::holds_alternative<Null>(this->dst)) {
#if defined(_WIN32)
constexpr auto null = "nul";
#elif defined(__linux__) || defined(__unix__)
constexpr auto null = "/dev/null";
#else
#error "Unsupported platform"
#endif
pass = test_exercise(n, std::ofstream(null, std::ios::out | std::ios::app), null);
} else {
return test_exercise(std::cout, n, nullptr);
const auto path = fs::absolute(fs::path(XMAKE) / "log" / std::get<fs::path>(this->dst));
const auto path_string = path.string();
pass = test_exercise(n, std::ofstream(path, std::ios::out | std::ios::app), path_string.c_str());
}
{
std::lock_guard lock(this->mutex);
this->result.push_back(pass);
}
return *this;
}
14 changes: 13 additions & 1 deletion learn/test.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
#ifndef __TEST_H__
#define __TEST_H__

bool test_exercise(int n, const char *log);
#include <filesystem>
#include <mutex>
#include <variant>
#include <vector>

struct Console {};
struct Null {};
struct Log {
std::variant<Console, Null, std::filesystem::path> dst;
std::vector<bool> result;
std::mutex mutex;
Log &operator<<(unsigned int n);
};

#endif// __TEST_H__

0 comments on commit 192b569

Please sign in to comment.