Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "tensor_data_transfer.h"
12 : #include <map>
13 : #include <mutex>
14 : #include <sstream>
15 : #include <unordered_map>
16 :
17 : #include "data_common.h"
18 : #include "tdt_host_interface.h"
19 :
20 : #include "log_inner.h"
21 : #include "acl/acl_tdt_queue.h"
22 : #include "acl_tdt_queue/queue.h"
23 : #include "runtime/rt_mem_queue.h"
24 : #include "runtime/mem.h"
25 : #include "runtime/context.h"
26 : #include "runtime/rts/rts_mem.h"
27 : #include "utils/file_utils.h"
28 : #include "utils/data_type_utils.h"
29 :
30 : namespace {
31 : std::mutex aclChannleMutex;
32 : std::map<std::string, acltdtChannelHandle*> aclChannleMap;
33 : std::map<std::string, aclDataType> aclDataTypeStrMap = {
34 : {"bool", ACL_BOOL}, {"int8", ACL_INT8}, {"uint8", ACL_UINT8}, {"half", ACL_FLOAT16}, {"int16", ACL_INT16},
35 : {"uint16", ACL_UINT16}, {"float", ACL_FLOAT}, {"int32", ACL_INT32}, {"uint32", ACL_UINT32}, {"int64", ACL_INT64},
36 : {"uint64", ACL_UINT64}, {"double", ACL_DOUBLE}, {"string", ACL_STRING}};
37 : constexpr uint32_t VERSION_NAME = 1U;
38 : constexpr size_t TDT_TENSOR_ALIGNE_UNIT = 64UL;
39 : const std::vector<size_t> GEAR_SIZE{
40 : 1U * 1024U * 1024U, 10U * 1024U * 1024U, 100U * 1024U * 1024U, 500U * 1024U * 1024U};
41 6 : size_t Get64AlignedSize(const size_t size)
42 : {
43 6 : return (size + TDT_TENSOR_ALIGNE_UNIT - 1UL) / TDT_TENSOR_ALIGNE_UNIT * TDT_TENSOR_ALIGNE_UNIT;
44 : }
45 :
46 : using TdtHostInitFunc = int32_t (*)(uint32_t);
47 : using TdtHostPreparePopDataFunc = int32_t (*)();
48 : using TdtHostPopDataFunc = int32_t (*)(const std::string&, std::vector<tdt::DataItem>&);
49 : using TdtHostPushDataFunc = int32_t (*)(const std::string&, const std::vector<tdt::DataItem>&, uint32_t deviceId);
50 : using TdtHostStopFunc = int32_t (*)(const std::string&);
51 : using TdtHostDestroyFunc = int32_t (*)();
52 :
53 : #ifndef RUN_TEST
54 : void* GetHandler()
55 : {
56 : std::string soPath;
57 : if (acl::file_utils::GetSoRealPath(soPath) != ACL_SUCCESS) {
58 : ACL_LOG_ERROR("Get libacl_tdt_channel.so path failed.");
59 : return nullptr;
60 : }
61 : std::string soName = soPath + "libdatatransfer.so";
62 : // Load the "libdatatransfer.so" library until the program ends. During the process, Dlclose is not invoked
63 : // to prevent the destruction of the global state information saved in ibdatatransfer.so.
64 : void* handler = mmDlopen(soName.c_str(), RTLD_NOW | RTLD_GLOBAL);
65 : if (handler == nullptr) {
66 : ACL_LOG_ERROR(
67 : "The corresponding dependent dynamic library cannot be found. "
68 : "Please confirm whether the environment supports it and if the extension package has been correctly "
69 : "installed. "
70 : "soName is %s.",
71 : soName.c_str());
72 : }
73 : return handler;
74 : }
75 : #endif
76 :
77 6 : void* GetFunction(const std::string& func_name)
78 : {
79 : #ifdef RUN_TEST
80 : std::unordered_map<std::string, void*> stubFunctionMap = {
81 0 : {"TdtHostInit", reinterpret_cast<void*>(&tdt::TdtHostInit)},
82 0 : {"TdtHostPushData", reinterpret_cast<void*>(&tdt::TdtHostPushData)},
83 0 : {"TdtHostDestroy", reinterpret_cast<void*>(&tdt::TdtHostDestroy)},
84 0 : {"TdtHostPreparePopData", reinterpret_cast<void*>(&tdt::TdtHostPreparePopData)},
85 0 : {"TdtHostPopData", reinterpret_cast<void*>(&tdt::TdtHostPopData)},
86 48 : {"TdtHostStop", reinterpret_cast<void*>(&tdt::TdtHostStop)}};
87 6 : auto it = stubFunctionMap.find(func_name);
88 6 : if (it != stubFunctionMap.end()) {
89 6 : return it->second;
90 : }
91 0 : return nullptr;
92 : #else
93 : static void* handler = GetHandler();
94 : if (handler == nullptr) {
95 : ACL_LOG_ERROR("Get handler failed when get %s function.", func_name.c_str());
96 : return nullptr;
97 : }
98 : void* func_ptr = mmDlsym(handler, func_name.c_str());
99 : if (func_ptr == nullptr) {
100 : ACL_LOG_ERROR(
101 : "The corresponding symbol cannot be found. Please confirm whether the installed extension package is "
102 : "correct, %s.",
103 : mmDlerror());
104 : }
105 : return func_ptr;
106 : #endif
107 12 : }
108 : } // namespace
109 :
110 : namespace acl {
111 4 : bool GetTensorShape(const std::string& dimsStr, std::vector<int64_t>& dims)
112 : {
113 : // change "[32,224,224,3]" => "32,224,224,3"
114 : // tensor_shape.size() - 2 is the second to last
115 4 : if (dimsStr.size() < 2) {
116 2 : ACL_LOG_INNER_ERROR("[Check][dimsStr]Invalid shape string: %s", dimsStr.c_str());
117 2 : return false;
118 : }
119 :
120 2 : std::string str = dimsStr.substr(1, dimsStr.size() - 2);
121 2 : if (!str.empty()) {
122 2 : std::string::size_type index = 0;
123 2 : while ((index = str.find(' ', index)) != std::string::npos) {
124 0 : (void)str.erase(index, 1);
125 : }
126 : }
127 2 : std::string split = ",";
128 2 : std::string::size_type pos2 = str.find(split);
129 2 : std::string::size_type pos1 = 0;
130 3 : while (pos2 != std::string::npos) {
131 : try {
132 1 : dims.push_back(std::stoll(str.substr(pos1, pos2 - pos1)));
133 0 : } catch (...) {
134 0 : ACL_LOG_INNER_ERROR("[Check][Shape]Invalid shape string: %s", dimsStr.c_str());
135 0 : return false;
136 0 : }
137 : // string::size_type can store the length of any string object
138 1 : pos1 = pos2 + split.size();
139 1 : pos2 = str.find(split, pos1);
140 : }
141 2 : if (pos1 != str.length()) {
142 : try {
143 3 : dims.push_back(std::stoll(str.substr(pos1)));
144 1 : } catch (...) {
145 1 : ACL_LOG_INNER_ERROR("[Check][Shape]Invalid shape string: %s", dimsStr.c_str());
146 1 : return false;
147 1 : }
148 : }
149 1 : return true;
150 2 : }
151 :
152 5 : aclError GetTdtDataTypeByAclDataType(acltdtTensorType aclType, tdt::TdtDataType& tdtDataType)
153 : {
154 5 : switch (aclType) {
155 1 : case ACL_TENSOR_DATA_END_OF_SEQUENCE: {
156 1 : tdtDataType = tdt::TDT_END_OF_SEQUENCE;
157 1 : break;
158 : }
159 2 : case ACL_TENSOR_DATA_TENSOR: {
160 2 : tdtDataType = tdt::TDT_TENSOR;
161 2 : break;
162 : }
163 1 : case ACL_TENSOR_DATA_ABNORMAL: {
164 1 : tdtDataType = tdt::TDT_ABNORMAL;
165 1 : break;
166 : }
167 1 : default: {
168 1 : acl::AclErrorLogManager::ReportInputError(
169 2 : acl::INVALID_VALUE_MSG, std::vector<const char*>({"func", "value", "param", "expect"}),
170 1 : std::vector<const char*>(
171 2 : {"Obtaining the tdt data type", acl::GetTensorTypeDesc(aclType), "aclType",
172 2 : "ACL_TENSOR_DATA_END_OF_SEQUENCE or ACL_TENSOR_DATA_TENSOR or ACL_TENSOR_DATA_ABNORMAL"}));
173 1 : return ACL_ERROR_INVALID_PARAM;
174 : }
175 : }
176 4 : return ACL_SUCCESS;
177 : }
178 :
179 12 : aclError GetTdtDataTypeByAclDataTypeV2(acltdtTensorType aclType, int32_t& tdtDataType)
180 : {
181 12 : switch (aclType) {
182 1 : case ACL_TENSOR_DATA_END_OF_SEQUENCE: {
183 1 : tdtDataType = 1;
184 1 : break;
185 : }
186 7 : case ACL_TENSOR_DATA_TENSOR: {
187 7 : tdtDataType = 0;
188 7 : break;
189 : }
190 1 : case ACL_TENSOR_DATA_ABNORMAL: {
191 1 : tdtDataType = 2;
192 1 : break;
193 : }
194 3 : default: {
195 3 : acl::AclErrorLogManager::ReportInputError(
196 6 : acl::INVALID_VALUE_MSG, std::vector<const char*>({"func", "value", "param", "expect"}),
197 3 : std::vector<const char*>(
198 6 : {"Obtaining the tdt data type", acl::GetTensorTypeDesc(aclType), "aclType",
199 6 : "ACL_TENSOR_DATA_END_OF_SEQUENCE or ACL_TENSOR_DATA_TENSOR or ACL_TENSOR_DATA_ABNORMAL"}));
200 3 : return ACL_ERROR_INVALID_PARAM;
201 : }
202 : }
203 9 : return ACL_SUCCESS;
204 : }
205 :
206 6 : aclError GetAclTypeByTdtDataType(tdt::TdtDataType tdtDataType, acltdtTensorType& aclType)
207 : {
208 6 : switch (tdtDataType) {
209 2 : case tdt::TDT_END_OF_SEQUENCE: {
210 2 : aclType = ACL_TENSOR_DATA_END_OF_SEQUENCE;
211 2 : break;
212 : }
213 2 : case tdt::TDT_TENSOR: {
214 2 : aclType = ACL_TENSOR_DATA_TENSOR;
215 2 : break;
216 : }
217 1 : case tdt::TDT_ABNORMAL: {
218 1 : aclType = ACL_TENSOR_DATA_ABNORMAL;
219 1 : break;
220 : }
221 1 : default: {
222 1 : acl::AclErrorLogManager::ReportInputError(
223 2 : acl::INVALID_VALUE_MSG, std::vector<const char*>({"func", "value", "param", "expect"}),
224 1 : std::vector<const char*>(
225 2 : {"Obtaining the tensor data type", acl::GetTdtDataTypeDesc(tdtDataType), "tdtDataType",
226 2 : "TDT_END_OF_SEQUENCE or TDT_TENSOR or TDT_ABNORMAL"}));
227 1 : return ACL_ERROR_UNSUPPORTED_DATA_TYPE;
228 : }
229 : }
230 5 : return ACL_SUCCESS;
231 : }
232 :
233 11 : aclError GetAclTypeByTdtDataTypeV2(int32_t tdtDataType, acltdtTensorType& aclType)
234 : {
235 11 : switch (tdtDataType) {
236 1 : case 1: {
237 1 : aclType = ACL_TENSOR_DATA_END_OF_SEQUENCE;
238 1 : break;
239 : }
240 6 : case 0: {
241 6 : aclType = ACL_TENSOR_DATA_TENSOR;
242 6 : break;
243 : }
244 1 : case 2: {
245 1 : aclType = ACL_TENSOR_DATA_ABNORMAL;
246 1 : break;
247 : }
248 1 : case 3: {
249 1 : aclType = ACL_TENSOR_DATA_SLICE_TENSOR;
250 1 : break;
251 : }
252 1 : case 4: {
253 1 : aclType = ACL_TENSOR_DATA_END_TENSOR;
254 1 : break;
255 : }
256 1 : default: {
257 1 : acl::AclErrorLogManager::ReportInputError(
258 2 : acl::INVALID_VALUE_MSG, std::vector<const char*>({"func", "value", "param", "expect"}),
259 1 : std::vector<const char*>(
260 2 : {"Obtaining the tensor data type", acl::GetTdtDataTypeDescV2(tdtDataType), "tdtDataType",
261 : "[TDT_TENSOR(0), TDT_END_OF_SEQUENCE(1), TDT_ABNORMAL(2), TDT_SLICE_TENSOR(3), "
262 2 : "TDT_END_TENSOR(4)]"}));
263 1 : return ACL_ERROR_UNSUPPORTED_DATA_TYPE;
264 : }
265 : }
266 10 : return ACL_SUCCESS;
267 : }
268 :
269 8 : aclError TensorDatasetSerializes(const acltdtDataset* dataset, std::vector<tdt::DataItem>& itemVec)
270 : {
271 8 : ACL_REQUIRES_NOT_NULL(dataset);
272 :
273 9 : for (size_t i = 0; i < dataset->blobs.size(); ++i) {
274 1 : tdt::DataItem item;
275 : tdt::TdtDataType tdtDataType;
276 1 : const auto ret = GetTdtDataTypeByAclDataType(dataset->blobs[i]->tdtType, tdtDataType);
277 1 : if (ret != ACL_SUCCESS) {
278 0 : ACL_LOG_INNER_ERROR(
279 : "[Check][Dataset]TensorDatasetSerializes failed, "
280 : "invalid tdt type %d",
281 : dataset->blobs[i]->tdtType);
282 0 : itemVec.clear();
283 0 : return ret;
284 : }
285 :
286 1 : item.dataType_ = tdtDataType;
287 1 : item.tensorShape_ = dataset->blobs[i]->dimsStr;
288 1 : item.tensorType_ = dataset->blobs[i]->dataTypeStr;
289 1 : item.dataLen_ = dataset->blobs[i]->dataLen;
290 1 : item.dataPtr_ = dataset->blobs[i]->dataPtr;
291 1 : itemVec.emplace_back(item);
292 1 : }
293 8 : return ACL_SUCCESS;
294 : }
295 :
296 9 : aclError TensorDatasetSerializesV2(const acltdtDataset* dataset, std::vector<acl::aclTdtDataItemInfo>& itemVec)
297 : {
298 9 : ACL_REQUIRES_NOT_NULL(dataset);
299 16 : for (size_t i = 0; i < dataset->blobs.size(); ++i) {
300 9 : acl::aclTdtDataItemInfo item;
301 : int32_t tdtDataType;
302 9 : const auto ret = GetTdtDataTypeByAclDataTypeV2(dataset->blobs[i]->tdtType, tdtDataType);
303 9 : if (ret != ACL_SUCCESS) {
304 2 : ACL_LOG_INNER_ERROR(
305 : "[Check][Dataset]TensorDatasetSerializes failed, "
306 : "invalid tdt type %d",
307 : dataset->blobs[i]->tdtType);
308 2 : return ret;
309 : }
310 :
311 7 : item.ctrlInfo.dataType = tdtDataType;
312 7 : item.ctrlInfo.tensorType = dataset->blobs[i]->dataType;
313 7 : item.ctrlInfo.dimNum = dataset->blobs[i]->dims.size();
314 7 : item.dims = dataset->blobs[i]->dims;
315 7 : item.ctrlInfo.dataLen = dataset->blobs[i]->dataLen;
316 7 : item.dataPtr = dataset->blobs[i]->dataPtr;
317 7 : itemVec.emplace_back(item);
318 7 : ACL_LOG_DEBUG(
319 : "TensorDatasetSerializesWithQueue, dataType %d, tensorType %d, dimNum %u, dataLen %lu",
320 : item.ctrlInfo.dataType, item.ctrlInfo.tensorType, item.ctrlInfo.dimNum, item.ctrlInfo.dataLen);
321 9 : }
322 7 : return ACL_SUCCESS;
323 : }
324 :
325 8 : aclError TensorDatasetDeserializes(const std::vector<tdt::DataItem>& itemVec, acltdtDataset* dataset)
326 : {
327 8 : ACL_REQUIRES_NOT_NULL(dataset);
328 8 : if (dataset->blobs.size() != 0) {
329 4 : const std::string sizeVal = std::to_string(dataset->blobs.size());
330 4 : acl::AclErrorLogManager::ReportInputError(
331 8 : acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
332 4 : std::vector<const char*>(
333 4 : {"tdt data deserialization", sizeVal.c_str(), "dataset->blobs.size",
334 8 : "dataset must be empty before deserialization"}));
335 4 : return ACL_ERROR_INVALID_PARAM;
336 4 : }
337 4 : aclError ret = ACL_SUCCESS;
338 5 : for (size_t i = 0; i < itemVec.size(); ++i) {
339 : acltdtTensorType aclType;
340 3 : ret = GetAclTypeByTdtDataType(itemVec[i].dataType_, aclType);
341 3 : if (ret != ACL_SUCCESS) {
342 1 : ACL_LOG_INNER_ERROR(
343 : "[Check][Dataset]TensorDatasetDeserializes failed, invalid data type %d", itemVec[i].dataType_);
344 2 : break;
345 : }
346 :
347 2 : if (aclType == ACL_TENSOR_DATA_TENSOR) {
348 1 : std::vector<int64_t> dims;
349 1 : if (!GetTensorShape(itemVec[i].tensorShape_, dims)) {
350 1 : ACL_LOG_INNER_ERROR(
351 : "[Check][TensorDataset]TensorDatasetDeserializes failed, "
352 : "invalid tensor shape[%s]",
353 : itemVec[i].tensorShape_.c_str());
354 1 : ret = ACL_ERROR_INTERNAL_ERROR;
355 1 : break;
356 : }
357 :
358 0 : std::map<std::string, aclDataType>::const_iterator iter = aclDataTypeStrMap.find(itemVec[i].tensorType_);
359 0 : if (iter == aclDataTypeStrMap.cend()) {
360 0 : ACL_LOG_INNER_ERROR(
361 : "[Deserialize][TensorDataset]TensorDatasetDeserializes failed, "
362 : "unknown data type[%s]",
363 : itemVec[i].tensorType_.c_str());
364 0 : ret = ACL_ERROR_INTERNAL_ERROR;
365 0 : break;
366 : }
367 0 : const aclDataType dataType = iter->second;
368 : acltdtDataItem* item = new (std::nothrow) acltdtDataItem(
369 0 : aclType, &dims[0], dims.size(), itemVec[i].tensorShape_, dataType, itemVec[i].tensorType_,
370 0 : itemVec[i].dataPtr_, itemVec[i].dataLen_);
371 0 : if (item == nullptr) {
372 0 : ACL_LOG_ERROR("[Check][Item]TensorDatasetDeserializes alloc failed");
373 0 : std::string sizeStr = std::to_string(sizeof(acltdtDataItem));
374 0 : acl::AclErrorLogManager::ReportInputError(
375 0 : acl::ALLOC_MEMORY_FAILED_MSG, std::vector<const char*>({"buf_size", "alloc_interface"}),
376 0 : std::vector<const char*>({sizeStr.c_str(), "new"}));
377 0 : ret = ACL_ERROR_BAD_ALLOC;
378 0 : break;
379 0 : }
380 0 : dataset->blobs.push_back(item);
381 1 : } else {
382 : acltdtDataItem* item = new (std::nothrow) acltdtDataItem(
383 1 : aclType, nullptr, 0, itemVec[i].tensorShape_, ACL_DT_UNDEFINED, itemVec[i].tensorType_,
384 2 : itemVec[i].dataPtr_, itemVec[i].dataLen_);
385 1 : if (item == nullptr) {
386 0 : ACL_LOG_INNER_ERROR("[Check][Item]TensorDatasetDeserializes alloc failed");
387 0 : ret = ACL_ERROR_BAD_ALLOC;
388 0 : break;
389 : }
390 1 : dataset->blobs.push_back(item);
391 : }
392 : }
393 :
394 4 : if (ret != ACL_SUCCESS) {
395 2 : for (size_t i = 0; i < dataset->blobs.size(); ++i) {
396 0 : ACL_DELETE_AND_SET_NULL(dataset->blobs[i]);
397 : }
398 2 : dataset->blobs.clear();
399 : }
400 4 : dataset->freeSelf = true;
401 4 : return ret;
402 : }
403 :
404 6 : aclError TensorDatasetDeserializesV2(const std::vector<acl::aclTdtDataItemInfo>& itemVec, acltdtDataset* dataset)
405 : {
406 6 : ACL_REQUIRES_NOT_NULL(dataset);
407 6 : if (!dataset->blobs.empty() && !dataset->freeSelf) {
408 1 : const std::string sizeVal = std::to_string(dataset->blobs.size());
409 1 : acl::AclErrorLogManager::ReportInputError(
410 2 : acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
411 1 : std::vector<const char*>(
412 1 : {"tdt data deserialization", sizeVal.c_str(), "dataset->blobs.size",
413 2 : "dataset must be empty or freeSelf must be true before deserialization"}));
414 1 : return ACL_ERROR_INVALID_PARAM;
415 1 : }
416 5 : for (auto it = dataset->blobs.begin(); it != dataset->blobs.end(); ++it) {
417 0 : ACL_DELETE_AND_SET_NULL(*it);
418 : }
419 5 : dataset->blobs.clear();
420 5 : aclError ret = ACL_SUCCESS;
421 11 : for (size_t i = 0; i < itemVec.size(); ++i) {
422 : acltdtTensorType aclType;
423 6 : ret = GetAclTypeByTdtDataTypeV2(itemVec[i].ctrlInfo.dataType, aclType);
424 6 : if (ret != ACL_SUCCESS) {
425 0 : ACL_LOG_INNER_ERROR(
426 : "[Check][Dataset]Failed to convert TdtDataType %d to acltdtTensorType.", itemVec[i].ctrlInfo.dataType);
427 0 : break;
428 : }
429 6 : if ((aclType == ACL_TENSOR_DATA_TENSOR) || (aclType == ACL_TENSOR_DATA_SLICE_TENSOR) ||
430 1 : (aclType == ACL_TENSOR_DATA_END_TENSOR)) {
431 5 : if (itemVec[i].ctrlInfo.version == static_cast<int32_t>(VERSION_NAME)) {
432 : void* dataReal =
433 3 : (itemVec[i].priorityDataPtr_ != nullptr) ? itemVec[i].priorityDataPtr_ : itemVec[i].dataPtr.get();
434 3 : dataset->name.assign(static_cast<char*>(dataReal), itemVec[i].ctrlInfo.dataLen);
435 3 : ACL_LOG_INFO("get dataset name is %s", dataset->name.c_str());
436 3 : continue;
437 3 : }
438 2 : std::vector<int64_t> dims = itemVec[i].dims;
439 2 : const aclDataType dataType = static_cast<aclDataType>(itemVec[i].ctrlInfo.tensorType);
440 : acltdtDataItem* item = new (std::nothrow) acltdtDataItem(
441 10 : aclType, &dims[0], dims.size(), "", dataType, "", itemVec[i].dataPtr, itemVec[i].ctrlInfo.dataLen);
442 2 : if (item == nullptr) {
443 0 : ACL_LOG_INNER_ERROR("[Check][Item]TensorDatasetDeserializes alloc failed");
444 0 : ret = ACL_ERROR_BAD_ALLOC;
445 0 : break;
446 : }
447 2 : item->sliceNum = itemVec[i].ctrlInfo.sliceNum;
448 2 : item->sliceId = itemVec[i].ctrlInfo.sliceId;
449 2 : item->priorityData_ = itemVec[i].priorityDataPtr_;
450 2 : dataset->blobs.push_back(item);
451 4 : } else {
452 : acltdtDataItem* item = new (std::nothrow) acltdtDataItem(
453 5 : aclType, nullptr, 0, "", ACL_DT_UNDEFINED, "", itemVec[i].dataPtr, itemVec[i].ctrlInfo.dataLen);
454 1 : if (item == nullptr) {
455 0 : ACL_LOG_INNER_ERROR("[Check][Item]TensorDatasetDeserializes alloc failed");
456 0 : ret = ACL_ERROR_BAD_ALLOC;
457 0 : break;
458 : }
459 1 : item->priorityData_ = itemVec[i].priorityDataPtr_;
460 1 : dataset->blobs.push_back(item);
461 : }
462 : }
463 :
464 5 : if (ret != ACL_SUCCESS) {
465 0 : for (size_t i = 0; i < dataset->blobs.size(); ++i) {
466 0 : ACL_DELETE_AND_SET_NULL(dataset->blobs[i]);
467 : }
468 0 : dataset->blobs.clear();
469 : }
470 5 : dataset->freeSelf = true;
471 5 : return ret;
472 : }
473 :
474 28 : void GetTensorDimsString(const int64_t* dims, size_t dimNum, std::string& dimsStr)
475 : {
476 91 : for (size_t i = 0; i < dimNum; ++i) {
477 84 : dimsStr += std::to_string(dims[i]);
478 84 : if (i + 1 == dimNum) {
479 21 : break;
480 : }
481 63 : dimsStr.push_back(',');
482 : }
483 28 : dimsStr += "]";
484 28 : }
485 :
486 6 : aclError SaveCtrlSharedPtrToVec(
487 : const datasetMemType memType, rtMemQueueBuffInfo& qItem, const std::shared_ptr<uint8_t>& ctrlSharedPtr,
488 : std::vector<std::shared_ptr<uint8_t>>& ctrlSharedPtrVec)
489 : {
490 6 : void* ctrlPtr = ctrlSharedPtr.get();
491 6 : if (memType == MEM_DEVICE) {
492 3 : uint8_t* devPtr = nullptr;
493 3 : std::shared_ptr<uint8_t> ctrlSharedDevPtr;
494 3 : ctrlSharedDevPtr.reset(devPtr, [](void* p) {
495 3 : if (p != nullptr) {
496 0 : (void)rtFree(p);
497 : }
498 3 : });
499 3 : ACL_REQUIRES_RTS_OK_WARN_NOT_SUPPORT(
500 : rtMalloc(reinterpret_cast<void**>(&devPtr), qItem.len, RT_MEMORY_DEFAULT, acl::ACL_MODE_ID_U16), rtMalloc);
501 3 : ACL_REQUIRES_RTS_OK_WARN_NOT_SUPPORT(
502 : rtMemcpy(devPtr, qItem.len, ctrlPtr, qItem.len, RT_MEMCPY_HOST_TO_DEVICE), rtMemcpy);
503 3 : qItem.addr = devPtr;
504 3 : ctrlSharedPtrVec.push_back(ctrlSharedDevPtr);
505 3 : } else {
506 3 : qItem.addr = ctrlPtr;
507 3 : ctrlSharedPtrVec.push_back(ctrlSharedPtr);
508 : }
509 6 : return ACL_SUCCESS;
510 : }
511 :
512 4 : aclError UnpackageRecvDataInfo(uint8_t* outputHostAddr, size_t size, std::vector<acl::aclTdtDataItemInfo>& itemVec)
513 : {
514 4 : ItemInfo* head = reinterpret_cast<ItemInfo*>(outputHostAddr);
515 4 : uint32_t cnt = head->cnt;
516 4 : ACL_LOG_INFO("get tensor cnt is %u", cnt);
517 4 : size_t offset = 0;
518 5 : for (uint32_t i = 0; i < cnt; ++i) {
519 3 : if (offset + sizeof(ItemInfo) > size) {
520 1 : ACL_LOG_ERROR("offset is %zu, size is %zu", offset, size);
521 2 : return ACL_ERROR_FAILURE;
522 : }
523 2 : acl::aclTdtDataItemInfo item;
524 2 : ItemInfo* tmp = reinterpret_cast<ItemInfo*>(outputHostAddr + offset);
525 2 : item.ctrlInfo = *tmp;
526 2 : ACL_LOG_INFO(
527 : "UnpackInfo version %d, dataType %d, curCnt %u, cnt %u, tensorType %d, dimNum %u, "
528 : "dynamicBitSize %u, sliceNum %u, sliceId %u, dataLen %lu",
529 : tmp->version, tmp->dataType, tmp->curCnt, tmp->cnt, tmp->tensorType, tmp->dimNum, tmp->dynamicBitSize,
530 : static_cast<uint32_t>(tmp->sliceNum), static_cast<uint32_t>(tmp->sliceId), tmp->dataLen);
531 2 : offset += sizeof(ItemInfo);
532 :
533 3 : for (uint32_t j = 0; j < tmp->dimNum; ++j) {
534 2 : if (offset + sizeof(int64_t) > size) {
535 1 : ACL_LOG_ERROR("offset is %zu, size is %zu", offset, size);
536 1 : return ACL_ERROR_FAILURE;
537 : }
538 1 : int64_t dimTmp = *(reinterpret_cast<int64_t*>(outputHostAddr + offset));
539 1 : item.dims.push_back(dimTmp);
540 1 : ACL_LOG_INFO("current dims[%u] is %ld", j, dimTmp);
541 1 : offset += sizeof(int64_t);
542 : }
543 :
544 1 : if (offset + tmp->dataLen > size) {
545 0 : ACL_LOG_ERROR("offset is %zu, data len is %lu, size is %zu", offset, tmp->dataLen, size);
546 0 : return ACL_ERROR_FAILURE;
547 : }
548 1 : if (tmp->dataLen > 0U) {
549 1 : item.priorityDataPtr_ = outputHostAddr + offset;
550 1 : offset += tmp->dataLen;
551 : } else {
552 0 : ACL_LOG_INFO("data length is 0");
553 : }
554 1 : ACL_LOG_INFO("after %u tensor, offset is %zu", i + 1, offset);
555 1 : itemVec.push_back(item);
556 2 : }
557 2 : return ACL_SUCCESS;
558 : }
559 :
560 6 : aclError TensorDataitemSerialize(
561 : std::vector<acl::aclTdtDataItemInfo>& itemVec, const datasetMemType memType,
562 : std::vector<rtMemQueueBuffInfo>& qBufVec, std::vector<std::shared_ptr<uint8_t>>& ctrlSharedPtrVec)
563 : {
564 6 : uint32_t currentCnt = 0;
565 6 : size_t lastDataSize = 0U;
566 12 : for (size_t i = 0; i < itemVec.size(); ++i) {
567 6 : itemVec[i].ctrlInfo.curCnt = currentCnt;
568 6 : itemVec[i].ctrlInfo.cnt = itemVec.size();
569 6 : const size_t ctrlSize = sizeof(ItemInfo) + itemVec[i].dims.size() * sizeof(int64_t);
570 : // 64n + lastDataSize + 64n - lastDataSize
571 6 : const size_t alignedSize = Get64AlignedSize(ctrlSize + lastDataSize) - lastDataSize;
572 6 : itemVec[i].ctrlInfo.dynamicBitSize = alignedSize - sizeof(ItemInfo);
573 : std::shared_ptr<uint8_t> ctrlSharedPtr(
574 6 : new (std::nothrow) uint8_t[alignedSize], std::default_delete<uint8_t[]>());
575 6 : ACL_CHECK_MALLOC_RESULT_REPORT_RET(ctrlSharedPtr.get(), alignedSize, "new", ACL_ERROR_BAD_ALLOC);
576 6 : void* ctrlPtr = ctrlSharedPtr.get();
577 6 : ACL_LOG_DEBUG(
578 : "TensorDataitemSerialize alignedSize is %zu, ctrlSize is %zu, dynamicBitSize is %u, i is %zu,"
579 : " lastDataSize is %zu, shape size is %zu",
580 : alignedSize, ctrlSize, itemVec[i].ctrlInfo.dynamicBitSize, i, lastDataSize, itemVec[i].dims.size());
581 6 : auto memcpyRet = memcpy_s(ctrlPtr, alignedSize, &itemVec[i].ctrlInfo, sizeof(ItemInfo));
582 6 : if (memcpyRet != EN_OK) {
583 0 : ACL_LOG_INNER_ERROR(
584 : "[Call][MemCpy]call memcpy failed, result=%d, srcLen=%zu, dstLen=%zu", memcpyRet, sizeof(ItemInfo),
585 : alignedSize);
586 : }
587 6 : size_t offset = sizeof(ItemInfo);
588 30 : for (size_t j = 0; j < itemVec[i].dims.size(); ++j) {
589 24 : memcpyRet = memcpy_s(
590 24 : reinterpret_cast<uint8_t*>(ctrlPtr) + offset, alignedSize - offset, &itemVec[i].dims[j],
591 : sizeof(int64_t));
592 24 : if (memcpyRet != EN_OK) {
593 0 : ACL_LOG_INNER_ERROR(
594 : "[Call][MemCpy]call memcpy failed, result=%d, srcLen=%zu, dstLen=%zu", memcpyRet, sizeof(int64_t),
595 : alignedSize - offset);
596 : }
597 24 : offset += sizeof(int64_t);
598 : }
599 6 : rtMemQueueBuffInfo qItem = {};
600 6 : qItem.len = alignedSize;
601 6 : ACL_REQUIRES_OK(SaveCtrlSharedPtrToVec(memType, qItem, ctrlSharedPtr, ctrlSharedPtrVec));
602 6 : qBufVec.push_back(qItem);
603 :
604 6 : if (itemVec[i].ctrlInfo.dataLen > 0U) {
605 6 : rtMemQueueBuffInfo tmpQItem = {itemVec[i].dataPtr.get(), itemVec[i].ctrlInfo.dataLen};
606 6 : qBufVec.push_back(tmpQItem);
607 : } else {
608 0 : ACL_LOG_DEBUG("no need to insert data buf");
609 : }
610 : // current total size is (64n + lastDataSize)
611 6 : lastDataSize = itemVec[i].ctrlInfo.dataLen;
612 6 : ++currentCnt;
613 6 : }
614 6 : return ACL_SUCCESS;
615 : }
616 :
617 8 : aclError acltdtSendTensorV2(const acltdtChannelHandle* handle, const acltdtDataset* dataset, int32_t timeout)
618 : {
619 8 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
620 8 : std::vector<acl::aclTdtDataItemInfo> itemVec;
621 8 : auto ret = acl::TensorDatasetSerializesV2(dataset, itemVec);
622 8 : if (ret != ACL_SUCCESS) {
623 2 : ACL_LOG_INNER_ERROR(
624 : "[Serialize][Dataset]Failed to TensorDatasetSerializesV2, device is %u, name is %s.", handle->devId,
625 : handle->name.c_str());
626 2 : itemVec.clear();
627 2 : return ret;
628 : }
629 6 : std::vector<std::shared_ptr<uint8_t>> ctrlSharedPtrVec;
630 6 : std::vector<rtMemQueueBuffInfo> queueBufInfoVec;
631 6 : ret = acl::TensorDataitemSerialize(itemVec, dataset->memType, queueBufInfoVec, ctrlSharedPtrVec);
632 6 : if (ret != ACL_SUCCESS) {
633 0 : ACL_LOG_INNER_ERROR(
634 : "[Serialize][Dataset]Failed to TensorDataitemSerialize, device is %u, name is %s.", handle->devId,
635 : handle->name.c_str());
636 0 : return ret;
637 : }
638 :
639 6 : rtMemQueueBuff_t queueBuf = {nullptr, 0U, nullptr, 0U};
640 6 : queueBuf.buffCount = queueBufInfoVec.size();
641 6 : queueBuf.buffInfo = queueBufInfoVec.data();
642 6 : ret = rtMemQueueEnQueueBuff(handle->devId, handle->qid, &queueBuf, timeout);
643 6 : if (ret == ACL_ERROR_RT_QUEUE_FULL) {
644 2 : ACL_LOG_DEBUG("queue is full, device is %u, name is %s", handle->devId, handle->name.c_str());
645 2 : return ret;
646 : }
647 4 : if (ret != RT_ERROR_NONE) {
648 2 : return ret;
649 : }
650 2 : ACL_LOG_DEBUG("success to execute acltdtSendTensor, device is %u, name is %s", handle->devId, handle->name.c_str());
651 2 : return ACL_SUCCESS;
652 8 : }
653 :
654 11 : aclError EnsureCurrentThreadHasContext(const acltdtChannelHandle* handle)
655 : {
656 11 : rtContext_t rtCtx = nullptr;
657 11 : const rtError_t rtRet = rtCtxGetCurrent(&rtCtx);
658 11 : if ((rtRet != ACL_RT_SUCCESS) && (rtRet != ACL_ERROR_RT_CONTEXT_NULL)) {
659 1 : return rtRet;
660 : }
661 10 : if (rtCtx == nullptr) {
662 10 : if (handle->ctx_ == nullptr) {
663 10 : ACL_LOG_INFO("current thread need to create new context");
664 10 : ACL_REQUIRES_RTS_OK_WARN_NOT_SUPPORT(
665 : rtCtxCreateEx(&rtCtx, static_cast<uint32_t>(RT_CTX_NORMAL_MODE), static_cast<int32_t>(handle->devId)),
666 : rtCtxCreateEx);
667 10 : const_cast<acltdtChannelHandle*>(handle)->ctx_.reset(rtCtx, [](void* p) {
668 10 : if (p != nullptr) {
669 0 : (void)rtCtxDestroyEx(p);
670 : }
671 10 : });
672 : }
673 10 : ACL_REQUIRES_RTS_OK_WARN_NOT_SUPPORT(rtCtxSetCurrent(handle->ctx_.get()), rtCtxSetCurrent);
674 : }
675 10 : return ACL_SUCCESS;
676 : }
677 :
678 7 : static size_t GetMallocSize(const size_t bufLen)
679 : {
680 : // 超出当前档位就是bufLen, 在档位内就是上限值,并保存当前申请的值
681 21 : for (const size_t& size : GEAR_SIZE) {
682 19 : if (bufLen <= size) {
683 5 : return size;
684 : }
685 : }
686 2 : return bufLen;
687 : }
688 :
689 11 : aclError GetOrMallocHostMem(const acltdtChannelHandle* handle, acltdtDataset* dataset, size_t bufLen, void*& hostPtr)
690 : {
691 11 : ACL_LOG_INFO("current need size is %zu, current mem size is %zu", bufLen, dataset->sharedMemSize_);
692 11 : ACL_REQUIRES_OK(EnsureCurrentThreadHasContext(handle));
693 10 : if (bufLen > dataset->sharedMemSize_) {
694 7 : const size_t mallocSize = GetMallocSize(bufLen);
695 7 : ACL_LOG_INFO("need mallochost size %zu, bufLen is %zu", mallocSize, bufLen);
696 7 : void* outHostAddr = nullptr;
697 7 : ACL_REQUIRES_RTS_OK_WARN_NOT_SUPPORT(
698 : rtMallocHost(&outHostAddr, mallocSize, acl::ACL_MODE_ID_U16), rtMallocHost);
699 7 : ACL_CHECK_MALLOC_RESULT(outHostAddr);
700 7 : dataset->sharedMem_.reset(outHostAddr, [](void* p) {
701 7 : if (p != nullptr) {
702 7 : (void)rtFreeHost(p);
703 : }
704 7 : });
705 7 : dataset->sharedMemSize_ = mallocSize;
706 : }
707 10 : hostPtr = dataset->sharedMem_.get();
708 10 : return ACL_SUCCESS;
709 : }
710 :
711 5 : aclError acltdtReceiveTensorV2(const acltdtChannelHandle* handle, acltdtDataset* dataset, int32_t timeout)
712 : {
713 5 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
714 5 : size_t bufLen = 0;
715 5 : auto ret = rtMemQueuePeek(handle->devId, handle->qid, &bufLen, timeout);
716 5 : if (ret == ACL_ERROR_RT_QUEUE_EMPTY) {
717 1 : ACL_LOG_INFO("queue is empty, device is %u, name is %s", handle->devId, handle->name.c_str());
718 1 : return ret;
719 : }
720 4 : if (ret != RT_ERROR_NONE) {
721 1 : ACL_LOG_ERROR("peek queue [%u] failed", handle->qid);
722 1 : return ret;
723 : }
724 3 : ACL_LOG_INFO("peek queue [%u] success, bufLen is %zu", handle->qid, bufLen);
725 3 : if (bufLen == 0) {
726 0 : ACL_LOG_INNER_ERROR("[Check][bufLen]peek queue len cannot be zero");
727 0 : return ACL_ERROR_FAILURE;
728 : }
729 3 : void* hostPtr = nullptr;
730 3 : ACL_REQUIRES_OK(GetOrMallocHostMem(handle, dataset, bufLen, hostPtr));
731 :
732 3 : rtMemQueueBuff_t queueBuf = {nullptr, 0U, nullptr, 0U};
733 3 : rtMemQueueBuffInfo queueBufInfo = {hostPtr, bufLen};
734 3 : queueBuf.buffCount = 1;
735 3 : queueBuf.buffInfo = &queueBufInfo;
736 3 : ret = rtMemQueueDeQueueBuff(handle->devId, handle->qid, &queueBuf, 0);
737 3 : if (ret == ACL_ERROR_RT_QUEUE_EMPTY) {
738 1 : ACL_LOG_INFO("queue is empty, device is %u, name is %s", handle->devId, handle->name.c_str());
739 1 : return ret;
740 : }
741 2 : if (ret != RT_ERROR_NONE) {
742 1 : ACL_LOG_ERROR("Failed to rtMemQueueDeQueueBuf, device is %u, name is %s.", handle->devId, handle->name.c_str());
743 1 : return ret;
744 : }
745 :
746 1 : std::vector<acl::aclTdtDataItemInfo> itemVec;
747 1 : ret = acl::UnpackageRecvDataInfo(static_cast<uint8_t*>(hostPtr), bufLen, itemVec);
748 1 : if (ret != ACL_SUCCESS) {
749 0 : ACL_LOG_ERROR(
750 : "Failed to unpackage received data, device is %u, name is %s.", handle->devId, handle->name.c_str());
751 0 : return ret;
752 : }
753 1 : ret = acl::TensorDatasetDeserializesV2(itemVec, dataset);
754 1 : if (ret != ACL_SUCCESS) {
755 0 : ACL_LOG_INNER_ERROR(
756 : "[Deserialize][Dataset]Failed to deserialize tensor dataset, device is %u, name is %s.", handle->devId,
757 : handle->name.c_str());
758 0 : return ret;
759 : }
760 1 : ACL_LOG_INFO(
761 : "success to execute acltdtReceiveTensorV2, device is %u, name is %s.", handle->devId, handle->name.c_str());
762 1 : return ACL_SUCCESS;
763 1 : }
764 : } // namespace acl
765 :
766 2 : acltdtTensorType acltdtGetTensorTypeFromItem(const acltdtDataItem* dataItem)
767 : {
768 6 : ACL_REQUIRES_NOT_NULL_RET_INPUT_REPORT(dataItem, ACL_TENSOR_DATA_UNDEFINED);
769 1 : return dataItem->tdtType;
770 : }
771 :
772 2 : aclDataType acltdtGetDataTypeFromItem(const acltdtDataItem* dataItem)
773 : {
774 6 : ACL_REQUIRES_NOT_NULL_RET_INPUT_REPORT(dataItem, ACL_DT_UNDEFINED);
775 1 : return dataItem->dataType;
776 : }
777 :
778 1 : void* acltdtGetDataAddrFromItem(const acltdtDataItem* dataItem)
779 : {
780 1 : ACL_REQUIRES_NOT_NULL_RET_NULL_INPUT_REPORT(dataItem);
781 1 : if (dataItem->priorityData_ != nullptr) {
782 1 : return dataItem->priorityData_;
783 : }
784 0 : return dataItem->dataPtr.get();
785 : }
786 :
787 2 : size_t acltdtGetDataSizeFromItem(const acltdtDataItem* dataItem)
788 : {
789 6 : ACL_REQUIRES_NOT_NULL_RET_INPUT_REPORT(dataItem, 0);
790 1 : return dataItem->dataLen;
791 : }
792 :
793 2 : size_t acltdtGetDimNumFromItem(const acltdtDataItem* dataItem)
794 : {
795 6 : ACL_REQUIRES_NOT_NULL_RET_INPUT_REPORT(dataItem, 0);
796 1 : return dataItem->dims.size();
797 : }
798 :
799 1 : aclError acltdtGetSliceInfoFromItem(const acltdtDataItem* dataItem, size_t* sliceNum, size_t* sliceId)
800 : {
801 1 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataItem);
802 1 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(sliceNum);
803 1 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(sliceId);
804 1 : *sliceNum = dataItem->sliceNum;
805 1 : *sliceId = dataItem->sliceId;
806 1 : return ACL_SUCCESS;
807 : }
808 :
809 5 : aclError acltdtGetDimsFromItem(const acltdtDataItem* dataItem, int64_t* dims, size_t dimNum)
810 : {
811 5 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataItem);
812 : // check dims and dimNum
813 5 : if (dims == nullptr && dimNum != 0) {
814 2 : ACL_LOG_ERROR("[Check][Params]acltdtGetDimsFromItem failed, invalid dims and dimNum[%zu]", dimNum);
815 2 : std::string value = "nullptr/" + std::to_string(dimNum);
816 2 : acl::AclErrorLogManager::ReportInputError(
817 4 : acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
818 2 : std::vector<const char*>(
819 4 : {__func__, value.c_str(), "dims/dimNum", "If dims is nullptr, dimNum should be 0"}));
820 2 : return ACL_ERROR_INVALID_PARAM;
821 2 : }
822 :
823 3 : if (dims != nullptr && dimNum == 0) {
824 1 : ACL_LOG_ERROR("[Check][Params]acltdtGetDimsFromItem failed, invalid dims and dimNum[%zu]", dimNum);
825 1 : std::string value = std::to_string(*dims) + "/" + std::to_string(dimNum);
826 1 : acl::AclErrorLogManager::ReportInputError(
827 2 : acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
828 1 : std::vector<const char*>(
829 2 : {__func__, value.c_str(), "dims/dimNum", "If dims is not nullptr, dimNum should be greater than 0"}));
830 1 : return ACL_ERROR_INVALID_PARAM;
831 1 : }
832 :
833 2 : if (dimNum < dataItem->dims.size()) {
834 1 : ACL_LOG_ERROR(
835 : "[Check][dimNum]output dimNum[%zu] cannot be less than dims number[%zu]", dimNum, dataItem->dims.size());
836 1 : const std::string dimNumVal = std::to_string(dimNum);
837 : std::string errMsg = acl::AclErrorLogManager::FormatStr(
838 1 : "dimNum %zu cannot be less than the size of dataItem's dims %zu", dimNum, dataItem->dims.size());
839 1 : acl::AclErrorLogManager::ReportInputError(
840 2 : acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
841 2 : std::vector<const char*>({__func__, dimNumVal.c_str(), "dimNum", errMsg.c_str()}));
842 1 : return ACL_ERROR_INVALID_PARAM;
843 1 : }
844 :
845 5 : for (size_t i = 0; i < dataItem->dims.size(); ++i) {
846 4 : dims[i] = dataItem->dims[i];
847 : }
848 :
849 1 : return ACL_SUCCESS;
850 : }
851 :
852 5 : const char* acltdtGetDatasetName(const acltdtDataset* dataset)
853 : {
854 9 : ACL_REQUIRES_NOT_NULL_RET_INPUT_REPORT(dataset, nullptr);
855 4 : return dataset->name.c_str();
856 : }
857 :
858 32 : acltdtDataItem* acltdtCreateDataItem(
859 : acltdtTensorType tdtType, const int64_t* dims, size_t dimNum, aclDataType dataType, void* data, size_t size)
860 : {
861 32 : if (dims == nullptr && dimNum != 0) {
862 0 : ACL_LOG_ERROR("[Check][Params]acltdtCreateDataItem failed, invalid dims and dimNum[%zu]", dimNum);
863 0 : std::string value = "nullptr/" + std::to_string(dimNum);
864 0 : acl::AclErrorLogManager::ReportInputError(
865 0 : acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
866 0 : std::vector<const char*>(
867 0 : {__func__, value.c_str(), "dims/dimNum", "If dims is nullptr, dimNum should be 0"}));
868 0 : return nullptr;
869 0 : }
870 :
871 32 : if (dims != nullptr && dimNum == 0) {
872 2 : ACL_LOG_ERROR("[Check][Params]acltdtCreateDataItem failed, invalid dims and dimNum[%zu]", dimNum);
873 2 : std::string value = std::to_string(*dims) + "/" + std::to_string(dimNum);
874 2 : acl::AclErrorLogManager::ReportInputError(
875 4 : acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
876 2 : std::vector<const char*>(
877 4 : {__func__, value.c_str(), "dims/dimNum", "If dims is not nullptr, dimNum should be greater than 0"}));
878 2 : return nullptr;
879 2 : }
880 :
881 30 : constexpr size_t MAX_DIM_CNT = 128UL;
882 30 : if (dimNum > MAX_DIM_CNT) {
883 1 : ACL_LOG_ERROR(
884 : "[Check][Dimnum]acltdtCreateDataItem failed, dimNum[%zu] can't be larger than "
885 : "MAX_DIM_CNT[%zu]",
886 : dimNum, MAX_DIM_CNT);
887 1 : std::string expect = "less than or equal to " + std::to_string(MAX_DIM_CNT);
888 1 : const std::string dimNumVal = std::to_string(dimNum);
889 1 : acl::AclErrorLogManager::ReportInputError(
890 2 : acl::INVALID_VALUE_MSG, std::vector<const char*>({"func", "value", "param", "expect"}),
891 2 : std::vector<const char*>({__func__, dimNumVal.c_str(), "dimNum", expect.c_str()}));
892 1 : return nullptr;
893 1 : }
894 :
895 29 : if (tdtType != ACL_TENSOR_DATA_TENSOR) {
896 1 : if (dims != nullptr) {
897 1 : ACL_LOG_ERROR(
898 : "[Check][Dims]acltdtCreateDataItem failed, "
899 : "dims must be nullptr. tdtType is %d",
900 : tdtType);
901 1 : const std::string dimsVal = std::to_string(reinterpret_cast<uintptr_t>(dims));
902 1 : acl::AclErrorLogManager::ReportInputError(
903 2 : acl::INVALID_VALUE_MSG, std::vector<const char*>({"func", "value", "param", "expect"}),
904 2 : std::vector<const char*>({__func__, dimsVal.c_str(), "dims", "nullptr"}));
905 1 : return nullptr;
906 1 : }
907 0 : return new (std::nothrow) acltdtDataItem(tdtType, dims, dimNum, "[]", ACL_DT_UNDEFINED, "", nullptr, 0);
908 : }
909 :
910 : // tdtType: ACL_TENSOR_DATA_TENSOR
911 28 : std::string dimsStr = "[";
912 28 : acl::GetTensorDimsString(dims, dimNum, dimsStr);
913 :
914 28 : std::string typeStr;
915 184 : for (const auto& item : aclDataTypeStrMap) {
916 184 : if (item.second == dataType) {
917 28 : typeStr = item.first;
918 28 : break;
919 : }
920 : }
921 28 : std::shared_ptr<void> dataPtr;
922 28 : dataPtr.reset(data, [](const void*) {});
923 28 : return new (std::nothrow) acltdtDataItem(tdtType, dims, dimNum, dimsStr, dataType, typeStr, dataPtr, size);
924 28 : }
925 :
926 32 : aclError acltdtDestroyDataItem(acltdtDataItem* dataItem)
927 : {
928 32 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataItem);
929 31 : ACL_DELETE_AND_SET_NULL(dataItem);
930 31 : return ACL_SUCCESS;
931 : }
932 :
933 38 : acltdtDataset* acltdtCreateDataset() { return new (std::nothrow) acltdtDataset(); }
934 :
935 37 : aclError acltdtDestroyDataset(acltdtDataset* dataset)
936 : {
937 37 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataset);
938 37 : ACL_DELETE_AND_SET_NULL(dataset);
939 37 : return ACL_SUCCESS;
940 : }
941 :
942 33 : aclError acltdtAddDataItem(acltdtDataset* dataset, acltdtDataItem* dataItem)
943 : {
944 33 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataset);
945 33 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataItem);
946 32 : if (dataset->freeSelf) {
947 1 : acl::AclErrorLogManager::ReportInputError(
948 2 : acl::UNSUPPORTED_FEATURE_MSG, std::vector<const char*>({"feature", "reason"}),
949 2 : std::vector<const char*>({__func__, "item cannot be added because internal item already exists"}));
950 1 : return ACL_ERROR_FEATURE_UNSUPPORTED;
951 : }
952 31 : datasetMemType currentMemType = MEM_UNKNOWN;
953 31 : if (dataItem->dataPtr != nullptr) {
954 23 : rtPtrAttributes_t attr = {};
955 23 : ACL_REQUIRES_RTS_OK_WARN_NOT_SUPPORT(
956 : rtsPointerGetAttributes(dataItem->dataPtr.get(), &attr), rtsPointerGetAttributes);
957 23 : if ((attr.location.type == RT_MEMORY_LOC_HOST) || (attr.location.type == RT_MEMORY_LOC_UNREGISTERED)) {
958 13 : currentMemType = MEM_HOST;
959 : } else {
960 10 : currentMemType = MEM_DEVICE;
961 : }
962 : }
963 31 : if (dataset->memType == MEM_UNKNOWN) {
964 : // only MEM_UNKNOWN status can be refreshed
965 19 : dataset->memType = currentMemType;
966 : }
967 :
968 31 : if ((dataset->memType != MEM_UNKNOWN) && (currentMemType != MEM_UNKNOWN)) {
969 23 : if (dataset->memType != currentMemType) {
970 6 : ACL_LOG_ERROR("The memTypes in the dataset must be all host-side or device-side address");
971 6 : const std::string memTypeVal = acl::DatasetMemTypeToString(dataset->memType);
972 6 : acl::AclErrorLogManager::ReportInputError(
973 12 : acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
974 6 : std::vector<const char*>(
975 6 : {__func__, memTypeVal.c_str(), "dataset->memType",
976 12 : "The memTypes in the dataset must be all host-side or device-side address"}));
977 6 : return ACL_ERROR_INVALID_PARAM;
978 6 : }
979 : }
980 25 : dataset->blobs.push_back(dataItem);
981 25 : return ACL_SUCCESS;
982 : }
983 :
984 6 : acltdtDataItem* acltdtGetDataItem(const acltdtDataset* dataset, size_t index)
985 : {
986 10 : ACL_REQUIRES_NOT_NULL_RET_NULL_INPUT_REPORT(dataset);
987 5 : if (index >= dataset->blobs.size()) {
988 : std::string errMsg = acl::AclErrorLogManager::FormatStr(
989 4 : "index %zu is greater than or equal to dataset size %zu", index, dataset->blobs.size());
990 4 : const std::string indexVal = std::to_string(index);
991 4 : acl::AclErrorLogManager::ReportInputError(
992 8 : acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
993 8 : std::vector<const char*>({__func__, indexVal.c_str(), "index", errMsg.c_str()}));
994 4 : return nullptr;
995 4 : }
996 :
997 1 : return dataset->blobs[index];
998 : }
999 :
1000 4 : size_t acltdtGetDatasetSize(const acltdtDataset* dataset)
1001 : {
1002 8 : ACL_REQUIRES_NOT_NULL_RET_INPUT_REPORT(dataset, 0);
1003 3 : return dataset->blobs.size();
1004 : }
1005 :
1006 19 : acltdtChannelHandle* acltdtCreateChannel(uint32_t deviceId, const char* name)
1007 : {
1008 19 : ACL_REQUIRES_NOT_NULL_RET_NULL_INPUT_REPORT(name);
1009 21 : static TdtHostInitFunc tdtHostInit = (TdtHostInitFunc)GetFunction("TdtHostInit");
1010 19 : if (tdtHostInit == nullptr) {
1011 0 : return nullptr;
1012 : }
1013 19 : const auto ret = tdtHostInit(deviceId);
1014 19 : if (ret != 0) {
1015 1 : ACL_LOG_INNER_ERROR("[Init][Tdt]tdt host init failed, tdt result = %d", ret);
1016 1 : return nullptr;
1017 : }
1018 18 : acltdtChannelHandle* handle = new (std::nothrow) acltdtChannelHandle(deviceId, name);
1019 18 : if (handle != nullptr) {
1020 18 : if (!handle->recvName.empty()) {
1021 : static TdtHostPreparePopDataFunc tdtHostPreparePopData =
1022 3 : (TdtHostPreparePopDataFunc)GetFunction("TdtHostPreparePopData");
1023 1 : if (tdtHostPreparePopData == nullptr) {
1024 0 : return nullptr;
1025 : }
1026 1 : (void)tdtHostPreparePopData();
1027 : }
1028 : {
1029 18 : std::unique_lock<std::mutex> lk(aclChannleMutex);
1030 36 : aclChannleMap[name] = handle;
1031 18 : }
1032 : }
1033 18 : return handle;
1034 : }
1035 :
1036 9 : acltdtChannelHandle* acltdtCreateChannelWithCapacity(uint32_t deviceId, const char* name, size_t capacity)
1037 : {
1038 9 : ACL_REQUIRES_NOT_NULL_RET_NULL_INPUT_REPORT(name);
1039 9 : ACL_LOG_INFO("acltdtCreateChannelWithCapacity devId is %u, name is %s, capacity is %zu", deviceId, name, capacity);
1040 9 : if (strnlen(name, RT_MQ_MAX_NAME_LEN) + 1 > RT_MQ_MAX_NAME_LEN) {
1041 1 : ACL_LOG_ERROR("name [%s] length %zu cannot be larger than %d", name, (strlen(name) + 1U), RT_MQ_MAX_NAME_LEN);
1042 : std::string errMsg = acl::AclErrorLogManager::FormatStr(
1043 1 : "name [%s] length %zu cannot be larger than %d", name, (strlen(name) + 1U), RT_MQ_MAX_NAME_LEN);
1044 1 : acl::AclErrorLogManager::ReportInputError(
1045 2 : acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
1046 2 : std::vector<const char*>({__func__, name, "name", errMsg.c_str()}));
1047 1 : return nullptr;
1048 1 : }
1049 8 : acltdtChannelHandle* handle = new (std::nothrow) acltdtChannelHandle(deviceId, name);
1050 8 : ACL_CHECK_MALLOC_RESULT_REPORT_RET(handle, sizeof(acltdtChannelHandle), "new", nullptr);
1051 8 : handle->isTdtProcess = false;
1052 8 : acltdtQueueAttr attr{};
1053 8 : const size_t count = strlen(name) + 1U;
1054 8 : const auto ret = memcpy_s(attr.name, RT_MQ_MAX_NAME_LEN, name, count);
1055 8 : if (ret != EN_OK) {
1056 0 : const std::string retCode = std::to_string(ret);
1057 0 : std::stringstream ss;
1058 0 : ss << std::hex << "name=0x" << reinterpret_cast<uintptr_t>(name) << ", dest=0x"
1059 0 : << reinterpret_cast<uintptr_t>(attr.name) << std::dec << ", dest_max=" << RT_MQ_MAX_NAME_LEN
1060 0 : << ", count=" << count << ".";
1061 0 : const std::string extendInfo = ss.str();
1062 0 : acl::AclErrorLogManager::ReportInputError(
1063 : acl::STANDARD_FUNC_FAILED_MSG,
1064 0 : std::vector<const char*>({"func1", "func2", "ret_code", "reason", "extend_info"}),
1065 0 : std::vector<const char*>({__func__, "memcpy_s", retCode.c_str(), strerror(ret), extendInfo.c_str()}));
1066 0 : ACL_LOG_ERROR(
1067 : "[Call][MemCpy]call memcpy failed, result=%d, srcLen=%zu, dstLen=%d", ret, count, RT_MQ_MAX_NAME_LEN);
1068 0 : ACL_DELETE_AND_SET_NULL(handle);
1069 0 : return nullptr;
1070 0 : }
1071 8 : attr.depth = static_cast<uint32_t>(capacity);
1072 8 : attr.workMode = RT_MQ_MODE_DEFAULT;
1073 8 : attr.flowCtrlFlag = false;
1074 8 : attr.flowCtrlDropTime = 0;
1075 8 : attr.overWriteFlag = false;
1076 : // queue init should be invoked when device is open
1077 8 : const auto rtError = rtMemQueueInit(deviceId);
1078 8 : if (rtError == ACL_ERROR_RT_FEATURE_NOT_SUPPORT) {
1079 1 : ACL_LOG_INFO("queue init failed due to runtime does not support.");
1080 1 : ACL_DELETE_AND_SET_NULL(handle);
1081 1 : return nullptr;
1082 : }
1083 7 : if ((rtError != RT_ERROR_NONE) && (rtError != ACL_ERROR_RT_REPEATED_INIT)) {
1084 1 : ACL_LOG_INNER_ERROR("queue init failed, rtError is %d", rtError);
1085 1 : ACL_DELETE_AND_SET_NULL(handle);
1086 1 : return nullptr;
1087 : }
1088 6 : const rtError_t rtErr = rtMemQueueCreate(static_cast<int32_t>(deviceId), &attr, &handle->qid);
1089 6 : if (rtErr != RT_ERROR_NONE) {
1090 1 : ACL_DELETE_AND_SET_NULL(handle);
1091 1 : return nullptr;
1092 : }
1093 5 : ACL_LOG_INFO(
1094 : "acltdtCreateChannelWithCapacity devId is %u, name is %s, real name is %s, qid is %u", deviceId,
1095 : handle->name.c_str(), name, handle->qid);
1096 5 : return handle;
1097 : }
1098 :
1099 2 : aclError acltdtStopChannel(acltdtChannelHandle* handle)
1100 : {
1101 2 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
1102 2 : ACL_LOG_INFO("start to acltdtStopChannel, device is %u, name is %s", handle->devId, handle->name.c_str());
1103 2 : if (!handle->isTdtProcess) {
1104 0 : ACL_LOG_INFO("new process , stop channel is no use");
1105 0 : return ACL_SUCCESS;
1106 : }
1107 2 : if (!handle->recvName.empty()) {
1108 3 : static TdtHostStopFunc tdtHostStop = (TdtHostStopFunc)GetFunction("TdtHostStop");
1109 1 : if (tdtHostStop == nullptr) {
1110 0 : return ACL_ERROR_FAILURE;
1111 : }
1112 1 : const auto ret = tdtHostStop(handle->recvName);
1113 1 : if (ret != 0) {
1114 1 : ACL_LOG_INNER_ERROR(
1115 : "[Init][Tdt]tdt host stop failed for channel %s, tdt result = %d", handle->name.c_str(), ret);
1116 1 : return ACL_ERROR_FAILURE;
1117 : }
1118 : }
1119 1 : ACL_LOG_INFO("acltdtStopChannel success, device is %u, name is %s", handle->devId, handle->name.c_str());
1120 1 : return ACL_SUCCESS;
1121 : }
1122 :
1123 23 : aclError acltdtDestroyChannel(acltdtChannelHandle* handle)
1124 : {
1125 23 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
1126 23 : ACL_LOG_INFO("start to acltdtDestroyChannel, device is %u, name is %s", handle->devId, handle->name.c_str());
1127 23 : if (!handle->isTdtProcess) {
1128 7 : ACL_REQUIRES_RTS_OK_WARN_NOT_SUPPORT(
1129 : rtMemQueueDestroy(static_cast<int32_t>(handle->devId), handle->qid), rtMemQueueDestroy);
1130 7 : ACL_LOG_INFO("acltdtDestroyChannel success, device is %u, name is %s", handle->devId, handle->name.c_str());
1131 7 : ACL_DELETE_AND_SET_NULL(handle);
1132 7 : return ACL_SUCCESS;
1133 : }
1134 16 : std::unique_lock<std::mutex> lk(aclChannleMutex);
1135 16 : (void)aclChannleMap.erase(handle->name);
1136 16 : if (aclChannleMap.size() == 0) {
1137 17 : static TdtHostDestroyFunc tdtHostDestroy = (TdtHostDestroyFunc)GetFunction("TdtHostDestroy");
1138 15 : if (tdtHostDestroy == nullptr) {
1139 0 : return ACL_ERROR_FAILURE;
1140 : }
1141 15 : const auto ret = tdtHostDestroy();
1142 15 : if (ret != 0) {
1143 1 : ACL_LOG_INNER_ERROR("[Destroy][Tdt]TdtHostDestroy failed, tdt result = %d", ret);
1144 : }
1145 : }
1146 :
1147 16 : ACL_DELETE_AND_SET_NULL(handle);
1148 16 : return ACL_SUCCESS;
1149 16 : }
1150 :
1151 5 : aclError acltdtCleanChannel(acltdtChannelHandle* handle)
1152 : {
1153 5 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
1154 4 : ACL_LOG_INFO("start to acltdtCleanChannel, device is %u, name is %s", handle->devId, handle->name.c_str());
1155 4 : if (!handle->isTdtProcess) {
1156 2 : ACL_REQUIRES_RTS_OK_WARN_NOT_SUPPORT(rtMemQueueReset(handle->devId, handle->qid), rtMemQueueReset);
1157 1 : ACL_LOG_INFO("acltdtCleanChannel success, device is %u, name is %s", handle->devId, handle->name.c_str());
1158 1 : return ACL_SUCCESS;
1159 : }
1160 2 : return ACL_ERROR_FEATURE_UNSUPPORTED;
1161 : }
1162 :
1163 8 : aclError acltdtSendTensor(const acltdtChannelHandle* handle, const acltdtDataset* dataset, int32_t timeout)
1164 : {
1165 8 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
1166 7 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataset);
1167 6 : ACL_LOG_DEBUG("start to execute acltdtSendTensor, device is %u, name is %s", handle->devId, handle->name.c_str());
1168 6 : if (!handle->isTdtProcess) {
1169 2 : ACL_LOG_DEBUG("new process, use queue process");
1170 2 : return acl::acltdtSendTensorV2(handle, dataset, timeout);
1171 : }
1172 : // -1 represents infinite wait, it is must be -1 now
1173 7 : ACL_CHECK_INVALID_PARAM_WITH_REASON(
1174 : timeout != -1, timeout, "Only never timeout is supported, timeout can only be set to -1");
1175 :
1176 3 : std::vector<tdt::DataItem> itemVec;
1177 3 : const auto ret = acl::TensorDatasetSerializes(dataset, itemVec);
1178 3 : if (ret != ACL_SUCCESS) {
1179 0 : ACL_LOG_INNER_ERROR(
1180 : "[Serialize][Dataset]Failed to TensorDatasetSerializes, device is %u, name is %s.", handle->devId,
1181 : handle->name.c_str());
1182 0 : itemVec.clear();
1183 0 : return ret;
1184 : }
1185 :
1186 5 : static TdtHostPushDataFunc tdtHostPushData = (TdtHostPushDataFunc)GetFunction("TdtHostPushData");
1187 3 : if (tdtHostPushData == nullptr) {
1188 0 : return ACL_ERROR_FAILURE;
1189 : }
1190 3 : int32_t sendRet = tdtHostPushData(handle->name, itemVec, 0);
1191 3 : if (sendRet != 0) {
1192 2 : ACL_LOG_INNER_ERROR(
1193 : "[Push][Data]Failed to push data, tdt result = %d, device is %u, name is %s.", sendRet, handle->devId,
1194 : handle->name.c_str());
1195 2 : return ACL_ERROR_FAILURE;
1196 : }
1197 :
1198 1 : ACL_LOG_DEBUG("success to execute acltdtSendTensor, device is %u, name is %s", handle->devId, handle->name.c_str());
1199 1 : return ACL_SUCCESS;
1200 3 : }
1201 :
1202 7 : aclError acltdtReceiveTensor(const acltdtChannelHandle* handle, acltdtDataset* dataset, int32_t timeout)
1203 : {
1204 7 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
1205 6 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataset);
1206 5 : ACL_LOG_INFO("start to execute acltdtReceiveTensor, device is %u, name is %s", handle->devId, handle->name.c_str());
1207 5 : if (!handle->isTdtProcess) {
1208 0 : ACL_LOG_INFO("new process, use queue process");
1209 0 : return acl::acltdtReceiveTensorV2(handle, dataset, timeout);
1210 : }
1211 : // -1 represents infinite wait, it is must be -1 now
1212 8 : ACL_CHECK_INVALID_PARAM_WITH_REASON(
1213 : timeout != -1, timeout, "Only never timeout is supported, timeout can only be set to -1");
1214 :
1215 4 : if (handle->recvName.empty()) {
1216 2 : ACL_LOG_ERROR(
1217 : "[Check][Recvname]it is not a receive channel, failed to receive, device is %u, name is %s", handle->devId,
1218 : handle->name.c_str());
1219 2 : return ACL_ERROR_INVALID_PARAM;
1220 : }
1221 :
1222 2 : std::vector<tdt::DataItem> itemVec;
1223 4 : static TdtHostPopDataFunc tdtHostPopData = (TdtHostPopDataFunc)GetFunction("TdtHostPopData");
1224 2 : if (tdtHostPopData == nullptr) {
1225 0 : return ACL_ERROR_FAILURE;
1226 : }
1227 2 : const int32_t recvRet = tdtHostPopData(handle->recvName, itemVec);
1228 2 : if (recvRet != 0) {
1229 1 : ACL_LOG_INNER_ERROR(
1230 : "[Pop][Data]Failed to receive, tdt result = %d, device is %u, name is %s.", recvRet, handle->devId,
1231 : handle->name.c_str());
1232 1 : return ACL_ERROR_FAILURE;
1233 : }
1234 :
1235 1 : const auto ret = acl::TensorDatasetDeserializes(itemVec, dataset);
1236 1 : if (ret != ACL_SUCCESS) {
1237 0 : ACL_LOG_INNER_ERROR(
1238 : "[Deserialize][Dataset]Failed to TensorDatasetDeserializes, device is %u, name is %s.", handle->devId,
1239 : handle->name.c_str());
1240 0 : return ret;
1241 : }
1242 :
1243 1 : ACL_LOG_INFO(
1244 : "success to execute acltdtReceiveTensor, device is %u, name is %s", handle->devId, handle->name.c_str());
1245 1 : return ACL_SUCCESS;
1246 2 : }
1247 :
1248 5 : aclError acltdtQueryChannelSize(const acltdtChannelHandle* handle, size_t* size)
1249 : {
1250 5 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
1251 4 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(size);
1252 3 : if (handle->isTdtProcess) {
1253 1 : ACL_LOG_DEBUG("acltdtQueryChannelSize is not supported");
1254 1 : return ACL_ERROR_FEATURE_UNSUPPORTED;
1255 : }
1256 2 : ACL_LOG_DEBUG("start to execute acltdtQueryChannelSize, device is %u, qid is %u", handle->devId, handle->qid);
1257 : rtMemQueueInfo_t info;
1258 2 : ACL_REQUIRES_RTS_OK(rtMemQueueQueryInfo(static_cast<int32_t>(handle->devId), handle->qid, &info));
1259 1 : *size = static_cast<size_t>(info.size);
1260 1 : ACL_LOG_DEBUG(
1261 : "success to execute acltdtQueryChannelSize, size is %zu, device is %u, qid is %u", *size, handle->devId,
1262 : handle->qid);
1263 1 : return ACL_SUCCESS;
1264 : }
|