1cf4c530b2fee57182b36784cfce53e79c477873
[platform/core/ml/nnfw.git] / runtime / contrib / heap_trace / tests / src / trace_test.cc
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *    http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "common_test_environment.h"
18 #include "file_content_manipulations.h"
19
20 #include "trace.h"
21
22 #include <CL/cl.h>
23
24 #include <experimental/filesystem>
25 #include <thread>
26 #include <atomic>
27
28 using namespace std;
29 namespace fs = experimental::filesystem;
30
31 extern unique_ptr<::Trace> GlobalTrace;
32
33 namespace backstage
34 {
35
36 struct Trace : TestEnv
37 {
38   Trace() : TestEnv("./trace_test.log") {}
39
40   void generateGarbageInTestLogFile();
41   template <typename MemType>
42   static void emulateAllocationEvent(size_t eventsPoolId, size_t numberOfEmulation,
43                                      size_t numberOfBytesPerOneEmulation, atomic_bool &isPauseNeed);
44 };
45
46 TEST_F(Trace,
47        must_create_log_file_with_name_defined_in_env_var_HEAP_TRACE_LOG_during_initialization)
48 {
49   ASSERT_TRUE(fs::exists("./trace_test.log"));
50 }
51
52 TEST_F(Trace, must_truncate_log_file_if_it_exists_during_initialization)
53 {
54   GlobalTrace.reset();
55   generateGarbageInTestLogFile();
56   GlobalTrace.reset(new ::Trace);
57   GlobalTrace.reset();
58
59   ASSERT_STREQ(getContentOfFile("./trace_test.log").c_str(),
60                "On CPU - Peak heap usage: 0 B, Total allocated: 0 B, Total deallocated: 0 B\nOn "
61                "GPU - Peak mem usage: 0 B, Total allocated: 0 B, Total deallocated: 0 B\n");
62 }
63
64 void Trace::generateGarbageInTestLogFile()
65 {
66   ofstream log("./trace_test.log");
67   log << string(256, 'a');
68 }
69
70 TEST_F(Trace, should_not_generate_any_records_in_log_during_creation)
71 {
72   GlobalTrace.reset();
73
74   ASSERT_STREQ(getContentOfFile("./trace_test.log").c_str(),
75                "On CPU - Peak heap usage: 0 B, Total allocated: 0 B, Total deallocated: 0 B\nOn "
76                "GPU - Peak mem usage: 0 B, Total allocated: 0 B, Total deallocated: 0 B\n");
77 }
78
79 TEST_F(Trace, can_signalize_to_users_if_it_is_ready_for_using)
80 {
81   ASSERT_FALSE(::Trace::Guard().isActive());
82 }
83
84 TEST_F(Trace, must_signalize_that_it_is_not_ready_for_using_until_it_is_not_created)
85 {
86   GlobalTrace.reset();
87   ASSERT_TRUE(::Trace::Guard().isActive());
88 }
89
90 TEST_F(Trace, should_work_correctly_in_multithreaded_environment)
91 {
92   constexpr size_t numberOfThreads = 10, numberOfEmulations = 100,
93                    numberOfBytesPerOneEmulation = 1024;
94   atomic_bool isPauseNeed{true};
95   array<thread, numberOfThreads> threads;
96   for (size_t i = 0; i < numberOfThreads / 2; ++i)
97   {
98     threads[i] = thread(emulateAllocationEvent<void *>, i, numberOfEmulations,
99                         numberOfBytesPerOneEmulation, ref(isPauseNeed));
100   }
101   for (size_t i = numberOfThreads / 2; i < numberOfThreads; ++i)
102   {
103     threads[i] = thread(emulateAllocationEvent<cl_mem>, i, numberOfEmulations,
104                         numberOfBytesPerOneEmulation, ref(isPauseNeed));
105   }
106
107   GlobalTrace.reset(new ::Trace);
108   isPauseNeed = false;
109
110   for (size_t i = 0; i < numberOfThreads; ++i)
111   {
112     threads[i].join();
113   }
114   GlobalTrace.reset();
115
116   string thisShouldBeInLogFile =
117       "Total allocated: " +
118       to_string(numberOfThreads / 2 * numberOfEmulations * numberOfBytesPerOneEmulation) +
119       " B, Total deallocated: " +
120       to_string(numberOfThreads / 2 * numberOfEmulations * numberOfBytesPerOneEmulation) + " B\n";
121   string andThisToo =
122       "Total allocated: " +
123       to_string(numberOfThreads / 2 * numberOfEmulations * numberOfBytesPerOneEmulation) +
124       " B, Total deallocated: " +
125       to_string(numberOfThreads / 2 * numberOfEmulations * numberOfBytesPerOneEmulation) + " B\n";
126   ASSERT_TRUE(getContentOfFile("./trace_test.log").find(thisShouldBeInLogFile) != string::npos);
127   ASSERT_TRUE(getContentOfFile("./trace_test.log").find(andThisToo) != string::npos);
128 }
129
130 template <typename MemType>
131 void Trace::emulateAllocationEvent(size_t eventsPoolId, size_t numberOfEmulation,
132                                    size_t numberOfBytesPerOneEmulation, atomic_bool &isPauseNeed)
133 {
134   while (isPauseNeed)
135   {
136     continue;
137   }
138
139   for (size_t i = 1; i <= numberOfEmulation; ++i)
140   {
141     GlobalTrace->logAllocationEvent((MemType)(i + numberOfEmulation * eventsPoolId),
142                                     numberOfBytesPerOneEmulation);
143   }
144
145   for (size_t i = 1; i <= numberOfEmulation; ++i)
146   {
147     GlobalTrace->logDeallocationEvent((MemType)(i + numberOfEmulation * eventsPoolId));
148   }
149 }
150
151 TEST_F(Trace, must_log_allocation_and_deallocation_events)
152 {
153   void *memOnCPU1 = (void *)1, *memOnCPU2 = (void *)3;
154   cl_mem memOnGPU1 = (cl_mem)2, memOnGPU2 = (cl_mem)4;
155   GlobalTrace->logAllocationEvent(memOnCPU1, 347);
156   GlobalTrace->logDeallocationEvent(memOnCPU1);
157   GlobalTrace->logAllocationEvent(memOnGPU2, 592);
158   GlobalTrace->logDeallocationEvent(memOnGPU2);
159   GlobalTrace->logAllocationEvent(memOnGPU1, 349);
160   GlobalTrace->logDeallocationEvent(memOnGPU1);
161   GlobalTrace->logAllocationEvent(memOnCPU2, 568);
162   GlobalTrace->logDeallocationEvent(memOnCPU2);
163   GlobalTrace.reset();
164
165   string shouldBeInLogFile = "On CPU - Peak heap usage: " + to_string(568) +
166                              " B, Total allocated: " + to_string(347 + 568) +
167                              " B, Total deallocated: " + to_string(347 + 568) +
168                              " B\n"
169                              "On GPU - Peak mem usage: " +
170                              to_string(592) + " B, Total allocated: " + to_string(592 + 349) +
171                              " B, Total deallocated: " + to_string(592 + 349) + " B\n";
172   ASSERT_STREQ(getContentOfFile("./trace_test.log").c_str(), shouldBeInLogFile.c_str());
173 }
174
175 } // namespace backstage