Skip to content

Commit 028996d

Browse files
authored
OS-level file mapping for JSON reads (#275)
1 parent c751af4 commit 028996d

4 files changed

Lines changed: 117 additions & 30 deletions

File tree

app/Graph/build.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,7 @@ void print_time_stats(Graph& graph) {
11401140
int sum = std::accumulate(elps_time.begin(), elps_time.end(), 0);
11411141
std::cout << "Elapsed inference time:" << sum << '\n';
11421142
std::cout << "!INFERENCE TIME INFO END!" << '\n';
1143+
graph.printLayerStats();
11431144
#else
11441145
(void)graph;
11451146
#endif

app/Graph/graph_build.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ int main(int argc, char* argv[]) {
3838
options.par_backend = ParBackend::kThreads;
3939
} else if (backend_str == "omp") {
4040
options.par_backend = ParBackend::kOmp;
41+
} else if (backend_str == "kokkos") {
42+
options.par_backend = ParBackend::kKokkos;
4143
} else {
4244
std::cerr << "Unknown parallel backend: " << backend_str
4345
<< ". Using default (Threads)." << '\n';

include/graph/graph.hpp

Lines changed: 65 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22
#include <algorithm>
33
#include <chrono>
4+
#include <iomanip>
45
#include <memory>
56
#include <queue>
67
#include <stdexcept>
@@ -14,6 +15,31 @@
1415
#include "runtime_options.hpp"
1516

1617
namespace it_lab_ai {
18+
static std::unordered_map<LayerType, std::string> label_map = {
19+
{kInput, "Input"},
20+
{kPooling, "Pooling"},
21+
{kElementWise, "Element-wise"},
22+
{kConvolution, "Convolution"},
23+
{kFullyConnected, "Dense"},
24+
{kFlatten, "Flatten"},
25+
{kConcat, "Concat"},
26+
{kDropout, "Dropout"},
27+
{kSplit, "Split"},
28+
{kBinaryOp, "BinaryOp"},
29+
{kTranspose, "Transpose"},
30+
{kMatmul, "MatMul"},
31+
{kReshape, "Reshape"},
32+
{kSoftmax, "Softmax"},
33+
{kReduce, "Reduce"},
34+
{kBatchNormalization, "Normalization"}};
35+
36+
struct LayerTimeStats {
37+
std::string layer_name;
38+
double total_time = 0.0;
39+
int call_count = 0;
40+
double min_time = std::numeric_limits<double>::max();
41+
double max_time = 0.0;
42+
};
1743

1844
struct BranchState {
1945
int ind_layer;
@@ -27,6 +53,7 @@ std::shared_ptr<Layer> layer_based_shared_copy(
2753
const std::shared_ptr<Layer>& layer, const RuntimeOptions& options);
2854

2955
class Graph {
56+
std::map<std::string, LayerTimeStats> layer_stats_;
3057
int BiggestSize_;
3158
int V_; // amount of ids
3259
std::vector<std::shared_ptr<Layer>> layers_;
@@ -383,8 +410,27 @@ class Graph {
383410
auto end = std::chrono::high_resolution_clock::now();
384411
auto elapsed =
385412
std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
386-
time_.push_back(static_cast<int>(elapsed.count()));
387-
time_layer_.push_back(layers_[current_layer]->getName());
413+
int elapsed_ms = static_cast<int>(elapsed.count());
414+
time_.push_back(elapsed_ms);
415+
416+
LayerType layer_type = layers_[current_layer]->getName();
417+
time_layer_.push_back(layer_type);
418+
419+
auto it = label_map.find(layer_type);
420+
std::string layer_name_str =
421+
(it != label_map.end()) ? it->second : "Unknown";
422+
423+
auto& stats = layer_stats_[layer_name_str];
424+
stats.total_time += elapsed_ms;
425+
stats.call_count++;
426+
427+
if (stats.call_count == 1) {
428+
stats.min_time = elapsed_ms;
429+
stats.max_time = elapsed_ms;
430+
} else {
431+
if (elapsed_ms < stats.min_time) stats.min_time = elapsed_ms;
432+
if (elapsed_ms > stats.max_time) stats.max_time = elapsed_ms;
433+
}
388434
#endif
389435
}
390436
}
@@ -408,25 +454,6 @@ class Graph {
408454
#ifdef ENABLE_STATISTIC_TIME
409455
std::vector<std::string> getTimeInfo() {
410456
std::vector<std::string> res;
411-
412-
std::unordered_map<LayerType, std::string> label_map = {
413-
{kInput, "Input"},
414-
{kPooling, "Pooling"},
415-
{kElementWise, "Element-wise"},
416-
{kConvolution, "Convolution"},
417-
{kFullyConnected, "Dense"},
418-
{kFlatten, "Flatten"},
419-
{kConcat, "Concat"},
420-
{kDropout, "Dropout"},
421-
{kSplit, "Split"},
422-
{kBinaryOp, "BinaryOp"},
423-
{kTranspose, "Transpose"},
424-
{kMatmul, "MatMul"},
425-
{kReshape, "Reshape"},
426-
{kSoftmax, "Softmax"},
427-
{kReduce, "Reduce"},
428-
{kBatchNormalization, "Normalization"}};
429-
430457
for (size_t i = 0; i < time_.size(); i++) {
431458
auto it = label_map.find(time_layer_[i]);
432459
std::string layer_name = (it != label_map.end()) ? it->second : "Unknown";
@@ -461,6 +488,23 @@ class Graph {
461488
return result;
462489
}
463490

491+
void printLayerStats() {
492+
std::cout << "\n========== LAYER PERFORMANCE STATISTICS ==========\n";
493+
std::cout << std::left << std::setw(20) << "Layer Type" << std::right
494+
<< std::setw(15) << "Total (ms)" << std::setw(12) << "Calls"
495+
<< std::setw(15) << "Avg (ms)" << std::setw(15) << "Min (ms)"
496+
<< std::setw(15) << "Max (ms)" << '\n';
497+
498+
for (const auto& [name, stats] : layer_stats_) {
499+
double avg = stats.total_time / stats.call_count;
500+
std::cout << std::left << std::setw(20) << name << std::right
501+
<< std::fixed << std::setprecision(3) << std::setw(15)
502+
<< stats.total_time << std::setw(12) << stats.call_count
503+
<< std::setw(15) << avg << std::setw(15) << stats.min_time
504+
<< std::setw(15) << stats.max_time << '\n';
505+
}
506+
}
507+
464508
[[nodiscard]] std::vector<int> getTraversalOrder() const {
465509
auto in_out_degrees = getInOutDegrees();
466510
std::vector<int> in_degree(V_);

src/Weights_Reader/reader_weights.cpp

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,64 @@
66
#include <stdexcept>
77
#include <vector>
88

9+
#ifdef _WIN32
10+
#include <windows.h>
11+
#else
12+
#include <fcntl.h>
13+
#include <sys/mman.h>
14+
#include <sys/stat.h>
15+
#include <unistd.h>
16+
#endif
17+
918
namespace it_lab_ai {
1019

1120
using json = nlohmann::json;
1221

1322
json read_json(const std::string& filename) {
14-
std::ifstream ifs(filename);
15-
if (!ifs.is_open()) {
16-
throw std::runtime_error("Failed to open JSON file: " + filename);
23+
#ifdef _WIN32
24+
HANDLE file = CreateFileA(filename.c_str(), GENERIC_READ, FILE_SHARE_READ,
25+
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
26+
if (file == INVALID_HANDLE_VALUE) {
27+
throw std::runtime_error("Cannot open file: " + filename);
28+
}
29+
30+
DWORD size = GetFileSize(file, NULL);
31+
if (size == 0) {
32+
CloseHandle(file);
33+
return json{};
34+
}
35+
36+
HANDLE mapping = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
37+
char* data = (char*)MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
38+
39+
json result = json::parse(data, data + size);
40+
41+
UnmapViewOfFile(data);
42+
CloseHandle(mapping);
43+
CloseHandle(file);
44+
return result;
45+
46+
#else
47+
int fd = open(filename.c_str(), O_RDONLY);
48+
if (fd == -1) {
49+
throw std::runtime_error("Cannot open file: " + filename);
1750
}
1851

19-
json model_data;
20-
try {
21-
ifs >> model_data;
22-
} catch (const json::parse_error& e) {
23-
throw std::runtime_error("JSON parse error: " + std::string(e.what()));
52+
struct stat sb;
53+
fstat(fd, &sb);
54+
55+
if (sb.st_size == 0) {
56+
close(fd);
57+
return json{};
2458
}
2559

26-
return model_data;
60+
char* data = (char*)mmap(nullptr, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
61+
json result = json::parse(data, data + sb.st_size);
62+
63+
munmap(data, sb.st_size);
64+
close(fd);
65+
return result;
66+
#endif
2767
}
2868

2969
void extract_values_from_json(const json& j, std::vector<float>& values) {

0 commit comments

Comments
 (0)