API Tạo Số Ngẫu Nhiên Địa Phương Trong CANN/ops-math

aclnnInplaceRandom

[Bản tải xuống miễn phí] ops-math - Thư viện toán học cơ bản cho các toán tử tính toán, giúp tăng tốc mạng trên NPU. Địa chỉ dự án: https://gitcode.com/cann/ops-math

Hỗ trợ sản phẩm

Sản phẩm Hỗ trợ
Ascend 950PR/Ascend 950DT
Atlas A3 (dòng huấn luyện/phân tích)
Atlas A2 (dòng huấn luyện/phân tích)
Atlas 200I/500 A2 (dòng phân tích) ×
Dòng phân tích Atlas ×
Dòng huấn luyện Atlas

Mô tả chức năng

Điền giá trị lấy mẫu từ phân phối đều rời rạc trong khoảng [từ, đến-1] vào tensor selfRef.

Nguyên mẫu hàm

Mỗi toán tử có hai bước gọi API: trước tiên gọi "aclnnInplaceRandomGetWorkspaceSize" để lấy kích thước workspace cần thiết và executor chứa quy trình tính toán, sau đó gọi "aclnnInplaceRandom" thực hiện tính toán.

aclnnStatus aclnnInplaceRandomGetWorkspaceSize(
  const aclTensor*      selfRef, 
  int64_t               from, 
  int64_t               to, 
  int64_t               seed, 
  int64_t               offset, 
  uint64_t*             workspaceSize, 
  aclOpExecutor**       executor)
aclnnStatus aclnnInplaceRandom(
  void*                 workspace, 
  uint64_t              workspaceSize,  
  aclOpExecutor*        executor, 
  aclrtStream           stream)

aclnnInplaceRandomGetWorkspaceSize

  • Thông số:
Tham số Nhập/Xuất Mô tả Ghi chú Loại dữ liệu Định dạng Kích thước (shape) Tensor không liên tục
selfRef (aclTensor*) Nhập/Xuất Tensor đầu vào/đầu ra. Hỗ trợ trường hợp tensor trống. BFLOAT16, FLOAT16, FLOAT32, DOUBLE, INT32, INT64, INT16, INT8, UINT8, BOOL, COMPLEX64, COMPLEX128 ND 0-8 ×
from (int64_t) Nhập Giới hạn trái của miền phân phối. Giá trị from phải nằm trong phạm vi kiểu dữ liệu của selfRef, from < to. INT64 - - -
to (int64_t) Nhập Giới hạn phải của miền phân phối. Giá trị to phải nằm trong phạm vi kiểu dữ liệu của selfRef. INT64 - - -
seed (int64_t) Nhập Hạt giống tạo số ngẫu nhiên ảnh hưởng đến chuỗi số. - INT64 - - -
offset (int64_t) Nhập Độ dịch chuyển ảnh hưởng đến vị trí chuỗi số. - INT64 - - -
workspaceSize (uint64_t*) Xuất Kích thước workspace cần cấp phát trên thiết bị. - - - - -
executor (aclOpExecutor**) Xuất Executor chứa quy trình tính toán. - - - - -
  • Dòng huấn luyện Atlas: Không hỗ trợ BFLOAT16.
  • Ascend 950PR/950DT: Không hỗ trợ COMPLEX64, COMPLEX128.
  • Giá trị trả về:

aclnnStatus: Xem mã trạng thái aclnn.

Giao diện đầu tiên kiểm tra tham số, báo lỗi khi:

Mã lỗi Mô tả
ACLNN_ERR_PARAM_NULLPTR selfRef là con trỏ null.
ACLNN_ERR_PARAM_INVALID Kiểu dữ liệu của selfRef không được hỗ trợ.
from >= to.
to vượt quá phạm vi kiểu dữ liệu.

aclnnInplaceRandom

  • Thông số:
Tham số Nhập/Xuất Mô tả
workspace Nhập Địa chỉ vùng nhớ workspace trên thiết bị.
workspaceSize Nhập Kích thước workspace do giao diện đầu tiên cung cấp.
executor Nhập Executor chứa quy trình tính toán.
stream Nhập Stream chỉ định luồng thực thi.
  • Giá trị trả về:

aclnnStatus: Xem mã trạng thái aclnn.

Lưu ý

  • Tính toán xác định:
  • aclnnInplaceRandom có triển khai xác định mặc định.

Ví dụ sử dụng

Mã nguồn tham khảo dưới đây, vui lòng tham khảo tài liệu biên dịch và chạy mẫu:

#include <iostream>
#include <vector>
#include "acl/acl.h"
#include "aclnnop/aclnn_random.h"

#define CHECK_RET(cond, return_expr) \
  do {                               \
    if (!(cond)) {                   \
      return_expr;                   \
    }                                \
  } while (0)

#define LOG_PRINT(message, ...)     \
  do {                              \
    printf(message, ##__VA_ARGS__); \
  } while (0)

int64_t GetShapeSize(const std::vector<int64_t>& shape) {
  int64_t shapeSize = 1;
  for (auto i : shape) {
    shapeSize *= i;
  }
  return shapeSize;
}

int Init(int32_t deviceId, aclrtStream* stream) {
  auto ret = aclInit(nullptr);
  CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);
  ret = aclrtSetDevice(deviceId);
  CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);
  ret = aclrtCreateStream(stream);
  CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);
  return 0;
}

template <typename T>
int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr,
                    aclDataType dataType, aclTensor** tensor) {
  auto size = GetShapeSize(shape) * sizeof(T);
  auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST);
  CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret);
  ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE);
  CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret);

  std::vector<int64_t> strides(shape.size(), 1);
  for (int64_t i = shape.size() - 2; i >= 0; i--) {
    strides[i] = shape[i + 1] * strides[i + 1];
  }

  *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND,
                            shape.data(), shape.size(), *deviceAddr);
  return 0;
}

int main() {
  int32_t deviceId = 0;
  aclrtStream stream;
  auto ret = Init(deviceId, &stream);
  CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);

  std::vector<int64_t> selfShape = {4, 2};
  void* selfDeviceAddr = nullptr;
  aclTensor* self = nullptr;
  std::vector<float> selfHostData = {1, 2, 3, 4, 5, 6, 7, 8};
  int64_t gioiHanTu = 0;
  int64_t gioiHanDen = 10;
  int64_t seed = 1234;
  int64_t offset = 0;
  ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self);
  CHECK_RET(ret == ACL_SUCCESS, return ret);

  uint64_t workspaceSize = 0;
  aclOpExecutor* executor;
  ret = aclnnInplaceRandomGetWorkspaceSize(self, gioiHanTu, gioiHanDen, seed, offset, &workspaceSize, &executor);
  CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnInplaceRandomGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);
  void* workspaceAddr = nullptr;
  if (workspaceSize > 0) {
    ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
    CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
  }
  ret = aclnnInplaceRandom(workspaceAddr, workspaceSize, executor, stream);
  CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnInplaceRandom failed. ERROR: %d\n", ret); return ret);

  ret = aclrtSynchronizeStream(stream);
  CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);

  auto size = GetShapeSize(selfShape);
  std::vector<float> resultData(size, 0);
  ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), selfDeviceAddr,
                    size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST);
  CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);
  for (int64_t i = 0; i < size; i++) {
    LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]);
  }

  aclDestroyTensor(self);
  aclrtFree(selfDeviceAddr);
  if (workspaceSize > 0) {
    aclrtFree(workspaceAddr);
  }
  aclrtDestroyStream(stream);
  aclrtResetDevice(deviceId);
  aclFinalize();

  return 0;
}

Thẻ: CANN ops-math NPU toán tử ngẫu nhiên xử lý tensor

Đăng vào ngày 15 tháng 8 lúc 21:10