1 /**
2 * Copyright 2019 Huawei Technologies Co., Ltd
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 #include <string>
17 #include <random>
18 #include "minddata/dataset/util/task_manager.h"
19 #include "minddata/dataset/util/circular_pool.h"
20 #include "minddata/dataset/util/services.h"
21 #include "common/common.h"
22 #include "utils/ms_utils.h"
23 #include "utils/log_adapter.h"
24 #include "./securec.h"
25
26 namespace common = mindspore::common;
27
28 using namespace mindspore::dataset;
29 using mindspore::MsLogLevel::INFO;
30 using mindspore::ExceptionType::NoExceptionType;
31 using mindspore::LogStream;
32
33 class MindDataTestCircularPool : public UT::Common {
34 public:
35 std::shared_ptr<MemoryPool> mp_;
36 TaskGroup vg_;
MindDataTestCircularPool()37 MindDataTestCircularPool() {}
SetUp()38 void SetUp() {
39 Status rc = CircularPool::CreateCircularPool(&mp_);
40 ASSERT_TRUE(rc.IsOk());
41 }
42 };
43
TestMem(MindDataTestCircularPool * tp,int32_t num_iterations)44 Status TestMem(MindDataTestCircularPool *tp, int32_t num_iterations) {
45 const uint64_t min = 19 * 1024; // 19k
46 const uint64_t max = 20 * 1024 * 1024; // 20M
47 std::mt19937 gen{std::random_device{}()};
48 std::uniform_int_distribution<uint64_t> dist(min, max);
49 TaskManager::FindMe()->Post();
50 for (int i = 0; i < num_iterations; i++) {
51 uint64_t old_sz = dist(gen);
52 uint64_t new_sz = dist(gen);
53 std::string str = "Allocate " + std::to_string(old_sz) +
54 " bytes of memory and then resize to " + std::to_string(new_sz);
55 MS_LOG(DEBUG) << str << std::endl;
56 std::string id = Services::GetUniqueID();
57 void *p;
58 RETURN_IF_NOT_OK(tp->mp_->Allocate(old_sz, &p));
59 // Copy the id to the start of the memory.
60 (void) memcpy_s(p, old_sz, common::SafeCStr(id), UNIQUEID_LEN);
61 RETURN_IF_NOT_OK(tp->mp_->Reallocate(&p, old_sz, new_sz));
62 int n = memcmp(p, common::SafeCStr(id), UNIQUEID_LEN);
63 if (n) {
64 RETURN_STATUS_UNEXPECTED("Expect match");
65 }
66 tp->mp_->Deallocate(p);
67 }
68 return Status::OK();
69 }
70
TEST_F(MindDataTestCircularPool,TestALLFunction)71 TEST_F(MindDataTestCircularPool, TestALLFunction) {
72 const int32_t iteration = 100;
73 Services::CreateInstance();
74 auto f = std::bind(TestMem, this, iteration);
75 for (int i = 0; i < 3; i++) {
76 vg_.CreateAsyncTask("TestMem", f);
77 }
78 vg_.join_all();
79 MS_LOG(DEBUG) << vg_.GetTaskErrorIfAny() << std::endl;
80 ASSERT_TRUE(vg_.GetTaskErrorIfAny().IsOk());
81 CircularPool *cp = dynamic_cast<CircularPool *>(mp_.get());
82 MS_LOG(DEBUG) << *cp << std::endl;
83 }
84
85