-
产品名称:MDC 610软件版本:MDC 610 1.99.102-0000000 问题现象(问题描述):摄像头程序在编译机上编译通过但是在MDC上显示Segmentation fault故障后已采取的措施:/示例代码:如下这是.c文件#include <iostream>#include <vector>#include <cstdint>#include <cstring>#include "camera.h" // 声明 CameraInit、CameraWaitEvents、CameraGetData、CameraData#include "ascend_hal.h" // 声明全局 halMbufFreeusing mdc::camera::CameraInit;using mdc::camera::CameraWaitEvents;using mdc::camera::CameraGetData;using mdc::camera::CameraData;int main(int argc, char* argv[]){ // 默认参数 uint32_t camId = 21; int32_t timeoutWait = 1000; int32_t timeoutGet = 1000; // 简单命令行解析 for (int i = 1; i < argc; ++i) { if (std::strcmp(argv[i], "--camera") == 0 && i+1 < argc) { camId = static_cast<uint32_t>(std::stoi(argv[++i])); } else if (std::strcmp(argv[i], "--wait-timeout") == 0 && i+1 < argc) { timeoutWait = std::stoi(argv[++i]); } else if (std::strcmp(argv[i], "--get-timeout") == 0 && i+1 < argc) { timeoutGet = std::stoi(argv[++i]); } else { std::cerr << "Usage: " << argv[0] << " [--camera ID] [--wait-timeout ms] [--get-timeout ms]\n"; return -1; } } // 1. 初始化摄像头 std::vector<uint32_t> initList = { camId }; int32_t ret = CameraInit(initList); if (ret != 0) { std::cerr << "CameraInit failed: " << ret << "\n"; return -1; } // 2. 等待事件 auto ready = CameraWaitEvents(timeoutWait); if (ready.empty()) { std::cerr << "No camera event\n"; return -1; } // 3. 获取数据 std::vector<CameraData> frames; ret = CameraGetData(camId, frames, timeoutGet); if (ret != 0 || frames.empty()) { std::cerr << "CameraGetData failed: " << ret << "\n"; return -1; } // 4. 打印第一帧信息 —— 替换下列字段为实际名称 CameraData &f = frames[0]; std::cout << "Camera ID: " << /* f.realCameraIdField */ 0 << "\n"; std::cout << "Timestamp: " << /* f.realTimestampField */ 0 << "\n"; std::cout << "Image size: " << /* f.realImgSizeField */ 0 << "\n"; std::cout << "Meta size: " << /* f.realMetaSizeField */ 0 << "\n"; // 5. (可选)解析 metaBuf // const uint8_t* meta = f.realMetaBufPtr; // TODO // size_t msize = f.realMetaSizeField; // TODO // for (size_t off = 0; off + 1 < msize; off += 2) { // uint16_t word = (uint16_t(meta[off]) << 8) | uint16_t(meta[off+1]); // std::cout << "0x" << std::hex << word << " "; // } // std::cout << std::dec << "\n"; // 6. 释放缓冲 for (auto &d : frames) { // TODO: 替换为实际 buf 指针成员 // ::halMbufFree(d.realImgBufPtr); // ::halMbufFree(d.realMetaBufPtr); } return 0;}这是CMakeLists.txtcmake_minimum_required(VERSION 3.10)project(camera_example CXX)# 读取交叉编译环境变量if(DEFINED ENV{CC}) set(CMAKE_C_COMPILER $ENV{CC})endif()if(DEFINED ENV{CXX}) set(CMAKE_CXX_COMPILER $ENV{CXX})endif()if(DEFINED ENV{SYSROOT}) set(CMAKE_SYSROOT $ENV{SYSROOT})endif()# 计算交叉编译器自带 include 路径get_filename_component(CLANG_BIN_DIR ${CMAKE_CXX_COMPILER} DIRECTORY)get_filename_component(CROSS_ROOT ${CLANG_BIN_DIR} DIRECTORY)set(CROSS_INCLUDE_DIR ${CROSS_ROOT}/include)# 通用编译/链接选项set(COMMON_FLAGS -O2 --target=aarch64-linux-gnu --sysroot=${CMAKE_SYSROOT})add_compile_options(${COMMON_FLAGS})add_link_options (${COMMON_FLAGS})# 生成可执行add_executable(camera_example camera_example.cpp)# 包含头文件路径target_include_directories(camera_example PRIVATE ${CROSS_INCLUDE_DIR} ${CMAKE_SYSROOT}/usr/include ${CMAKE_SYSROOT}/usr/include/driver)# 链接库路径target_link_directories(camera_example PRIVATE ${CMAKE_SYSROOT}/usr/lib64)# 链接 SDK 库(根据实际库名调整)find_library(LIB_CAMERA NAMES mdc_camera camera PATHS ${CMAKE_SYSROOT}/usr/lib64)find_library(LIB_MBUF NAMES mdc_mbuf PATHS ${CMAKE_SYSROOT}/usr/lib64)if(NOT LIB_CAMERA OR NOT LIB_MBUF) message(FATAL_ERROR "找不到 SDK 库 (libcamera.so / libmdc_camera.so 或 libmdc_mbuf.so)")endif()target_link_libraries(camera_example PRIVATE ${LIB_CAMERA} ${LIB_MBUF})这是Makefile文件# Makefile —— 读取环境变量:CC, CXX, SYSROOTSRC := camera_example.cppTARGET := camera_example# 交叉编译器根目录CROSS_ROOT := $(shell dirname $(shell dirname $(CXX)))CXXFLAGS := -O2 \ --target=aarch64-linux-gnu \ --sysroot=$(SYSROOT) \ -I$(SYSROOT)/usr/include \ -I$(SYSROOT)/usr/include/driver \ -I$(CROSS_ROOT)/includeLDFLAGS := --target=aarch64-linux-gnu \ --sysroot=$(SYSROOT) \ -L$(SYSROOT)/usr/lib64 \ -lmdc_camera \ -lmdc_mbufall: $(TARGET)$(TARGET): $(SRC)$(CXX) $(CXXFLAGS) $< -o $@ $(LDFLAGS)clean:rm -f $(TARGET).PHONY: all clean
yd_251998187
发表于2025-06-03 11:35:33
2025-06-03 11:35:33
最后回复
yd_251998187
2025-06-16 22:14:57
331 17 -
基于华为开发者空间使用 FastAPI 构建 MCP 天气查询服务案例介绍本案例将指导您在华为云开发者空间中使用 FastAPI 框架构建一个功能完整的 MCP(Model Context Protocol)天气查询服务。通过本案例,您将学会如何将传统的 REST API 转换为 MCP 工具,让 AI 模型能够实时获取天气信息并与用户进行智能交互。技术栈后端框架: FastAPI协议标准: MCP (Model Context Protocol)天气数据: 和风天气 API认证方式: JWT (JSON Web Token)客户端: Cherry Studio部署环境: 华为云开发者空间学习目标掌握 MCP 协议的基本概念和实现方式实现 AI 模型与外部服务的实时数据交互体验华为云开发者空间的开发便利性以及 Maas DeepSeek 模型服务的无缝集成案例内容1. 概述1.1 案例背景在传统的 AI 对话系统中,模型只能基于训练数据回答问题,无法获取实时信息。MCP 协议的出现解决了这一痛点,它允许 AI 模型通过标准化的接口调用外部工具和服务,获取实时数据。本案例选择天气查询作为示例,因为:实时性强: 天气数据需要实时获取,体现 MCP 的价值应用广泛: 天气查询是用户常见需求技术完整: 涵盖 API 调用、数据处理、错误处理等完整流程易于扩展: 可以基于此案例扩展更多功能1.2 适用对象企业用户:关注业务自动化、提升开发效率、集成AI能力,适合希望快速构建智能工具、提升企业数字化水平的团队。个人开发者:具备一定Python基础(或能借助 AI 辅助编程),关注技术创新与个人成长,适合希望掌握MCP协议、API开发与AI集成的开发者。高校学生:有编程基础(或能借助 AI 辅助编程),关注AI应用实践与创新能力培养,适合希望参与AI+云平台项目实训、提升综合开发能力的学生群体。1.3 案例时间准备阶段: 30 分钟(环境配置、账号注册)开发阶段: 20 分钟(代码编写、调试)测试阶段: 10 分钟(功能验证、MCP 集成)总计时间: 约 60 分钟1.4 案例流程环境准备API 注册项目初始化依赖安装核心代码开发JWT 认证实现天气接口开发MCP 集成本地测试客户端配置端到端验证1.5 资源总览本案例预计花费0元。资源类型名称/说明免费额度/价格备注开发资源华为云开发者空间0元免费注册使用Maas DeepSeek 模型服务0元免费额度,按需扩展和风天气开发者账号0元免费额度,1000次/天Cherry Studio 客户端0元开源免费API 配额和风天气免费版0元1000次/天Maas DeepSeek 模型服务0元免费额度注意事项:本案例基于免费额度,如需更高配额请自行申请。API 可能存在调用次数限制,超出免费额度需付费或申请扩容。2. 环境配置2.1 开发者空间配置步骤 1: 登录华为云领取免费云主机访问 华为云官网,注册并登录华为云账号点击“开发者->开发者空间”,进入。如果没有领取过云主机可以点击"立即体验"进行开通。步骤 2: 配置云主机访问开发者空间工作台, 点击"配置云主机"配置基础资源: CPU架构为 ARM,规格为 4 vCPUs 8 GB,操作系统为 Ubuntu ,镜像为 Ubuntu 24.04 Server定制版等待环境初始化完成后点击"打开云主机-进入桌面",打开云主机桌面2.2 MaaS 领取 DeepSeek步骤 1: 访问华为云 MaaS 服务在华为云控制台搜索"MaaS",点击进入 Maas 控制台区域选择西南-贵阳一,在左侧菜单栏,选择在线推理 > 预置服务 > 免费服务,选择DeepSeek-R1-32K模型,点击领取额度,领取200万免费token。步骤 2: 获取API地址和模型名称领取后点击调用说明*,可以获取到对应的API地址、模型名称。步骤 3: 获取 API 密钥点击“API Key管理-创建API Key“”,自定义标签和描述,点击确定创建API Key。(⚠️注意:API Key仅会在新建后显示一次,请及时复制并妥善保存,若API Key丢失,请新建API Key。)至此,我们获取到了所需的 API 地址、模型名称和 API 密钥。2.3 安装 Cherry Studio下载安装:使用云主机中的Firefox访问 [Cherry Studio 官网] https://cherry-studio.com根据操作系统下载对应版本,如 **Cherry-Studio-1.3.12-arm64.AppImage给下载的文件添加执行权限chmod +x Cherry-Studio-1.3.12-arm64.AppImage安装运行相关依赖sudo apt update sudo apt install zlib1g zlib1g-dev sudo add-apt-repository universe sudo apt install libfuse2运行安装包./Cherry-Studio-1.3.12-arm64.AppImage --no-sandbox基础配置:配置 DeepSeek 模型连接测试模型连接是否正常2.4 和风天气 API 注册(可选)💡 提示: 教程代码中已包含测试用的 API 配置,如无法使用请自行注册注册流程:访问 和风天气开发者平台 https://id.qweather.com/注册开发者账号并完成邮箱验证进入开发服务控制台创建项目并获取必要的认证信息获取配置信息:PROJECT_ID: 项目标识符KEY_ID: JWT 密钥标识PRIVATE_KEY: JWT 签名私钥WEATHER_API_HOST: API 服务地址访问[https://id.qweather.com/] https://id.qweather.com/ 注册账号,初次使用需绑定手机号和邮箱。注册成功后,点击菜单中的 开发服务控制台,进入开发控制台。点击项目管理-创建项目,创建一个项目,如 fastapi, 创建之后此步骤获得PROJECT_ID。点击项目如fastapi,进入项目详情页并点击创建凭据开始创建 JWT 凭据,需先在本地生成公私钥对再创建,创建之后此步骤获得PRIVATE_KEY和KEY_ID。(PS: 虽然 APIKey 更简单,但推荐使用JSON Web Token (JWT)的认证方式获得更高等级的安全性以及不受限的API请求)点击设置, 从开发者信息中获取 API Host,也就是WEATHER_API_HOST至此,我们天气查询 MCP 中需要用到的配置信息已经全部获取。3. 项目搭建3.1 项目初始化使用CodeArts IDE for Python创建项目工程或者使用脚本创建项目目录:mkdir qweather-mcp cd qweather-mcp安装依赖包:pip install fastapi uvicorn fastapi-mcp pyjwt cryptography requests -i https://repo.huaweicloud.com/repository/pypi/simple创建项目结构:qweather-mcp/ ├── main.py # 主程序文件 ├── requirements.txt # 依赖列表 ├── config.py # 配置文件(可选) └── README.md # 项目说明3.2 核心代码实现详细的代码实现包括:FastAPI 应用初始化JWT 认证机制天气 API 封装MCP 协议集成错误处理机制3.3 关键功能模块JWT 认证模块: 实现安全的 API 访问控制天气查询模块: 封装和风天气 API 调用MCP 集成模块: 将 REST API 转换为 MCP 工具数据模型模块: 定义请求和响应的数据结构3.4 代码实现我们创建 main.py 文件,并编写代码。3.4.1 引入依赖from fastapi import FastAPI, HTTPException, Depends, Query, status from fastapi.security import HTTPBearer from pydantic import BaseModel, Field from typing import List, Optional, Dict, Any import jwt import time import requests from datetime import datetime import base64 from cryptography.hazmat.primitives import serialization from cryptography.hazmat.backends import default_backend # 引入 fastapi_mcp from fastapi_mcp import FastApiMCP, AuthConfig3.4.2 配置天气服务 APIapp = FastAPI(title="天气查询API") # 配置项 - 在实际应用中应从环境变量或配置文件中读取 # PRIVATE_KEY = """YOUR_PRIVATE_KEY""" # PROJECT_ID = "YOUR_PROJECT_ID" # KEY_ID = "YOUR_KEY_ID" # WEATHER_API_HOST = "your_api_host" PRIVATE_KEY = "MC4CAQAwBQYDK2VwBCIEIG2wMZga50X1YDHmR8jkE5TGKNXpriFPXXCT/kgwZkcT" PROJECT_ID = "3MKPRE78RN" KEY_ID = "T8B7JMU7AY" WEATHER_API_HOST = "ky6mte27bb.re.qweatherapi.com" 3.4.3 定义响应 Model# 响应模型 class Location(BaseModel): name: str id: str lat: str lon: str adm2: str adm1: str country: str tz: str utcOffset: str isDst: str type: str rank: str fxLink: str class LocationResponse(BaseModel): code: str location: List[Location] class WeatherNow(BaseModel): obsTime: str temp: str feelsLike: str icon: str text: str wind360: str windDir: str windScale: str windSpeed: str humidity: str precip: str pressure: str vis: str cloud: str dew: str class ReferSources(BaseModel): sources: List[str] license: List[str] class WeatherResponse(BaseModel): code: str updateTime: str fxLink: str now: WeatherNow refer: ReferSources class JWTRequest(BaseModel): expiry_seconds: Optional[int] = 900 # 默认15分钟 custom_claims: Optional[dict] = None # 允许添加自定义声明 class WeatherQuery(BaseModel): city: str = Field(..., description="城市名,如:北京") 3.4.4 JWT 令牌生成# 解码并加载私钥 try: _der_key_bytes = base64.b64decode(PRIVATE_KEY) PRIVATE_KEY = serialization.load_der_private_key( _der_key_bytes, password=None, backend=default_backend() ) except Exception as e: print(f"关键错误:无法从配置加载EdDSA私钥。错误: {e}") PRIVATE_KEY = None if PRIVATE_KEY is None: raise RuntimeError(f"关键错误:EdDSA私钥加载失败,应用无法启动。错误: {e}") # 令牌缓存(简单实现,生产环境应使用Redis等缓存系统) token_cache = { "token": None, "expires_at": 0 } # Bearer Token 安全头 token_auth_scheme = HTTPBearer() EXPECTED_BEARER_TOKEN = "huaweicloud" # 定义期望的固定Token # Bearer Token 验证依赖 async def verify_bearer_token(token_payload = Depends(token_auth_scheme)): if token_payload.credentials != EXPECTED_BEARER_TOKEN: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="无效的认证凭据", headers={"WWW-Authenticate": "Bearer"}, ) return token_payload.credentials # 生成JWT令牌 def generate_jwt(expiry_seconds: int = 900): current_time = int(time.time()) # 构建标准JWT载荷 payload = { 'iat': current_time - 30, # 颁发时间(提前30秒,避免时钟偏差问题) 'exp': current_time + expiry_seconds, # 过期时间 'sub': PROJECT_ID # 主题(项目ID) } # JWT头部 headers = { 'kid': KEY_ID # 密钥ID } if PRIVATE_KEY is None: raise ValueError("JWT生成失败: 私钥未初始化或加载失败。") try: # 生成JWT encoded_jwt = jwt.encode(payload, PRIVATE_KEY, algorithm='EdDSA', headers=headers) # 更新缓存 token_cache["token"] = encoded_jwt token_cache["expires_at"] = current_time + expiry_seconds - 60 # 提前1分钟过期,确保安全 return encoded_jwt except Exception as e: raise ValueError(f"JWT生成失败: {str(e)}") # 获取有效的JWT令牌(如果缓存中有有效令牌则使用缓存,否则生成新令牌) def get_valid_token(): current_time = int(time.time()) # 检查缓存中的令牌是否有效 if token_cache["token"] and token_cache["expires_at"] > current_time: return token_cache["token"] # 生成新令牌 return generate_jwt() @app.post("/generate-jwt", operation_id="generate_jwt", tags=["JWT"]) async def create_jwt( request: JWTRequest = JWTRequest() ): """ 生成JWT令牌 - 使用EdDSA算法签名 - 默认有效期为15分钟 - 可以添加自定义声明 """ try: encoded_jwt = generate_jwt(request.expiry_seconds) current_time = int(time.time()) return { "jwt": encoded_jwt, "expires_at": datetime.fromtimestamp(current_time + request.expiry_seconds).isoformat(), "issued_at": datetime.fromtimestamp(current_time - 30).isoformat(), "valid_for_seconds": request.expiry_seconds } except Exception as e: raise HTTPException(status_code=500, detail=str(e)) 3.4.5 天气查询接口# 发送HTTP请求到天气API,并处理gzip压缩 def fetch_weather_api(endpoint: str, params: Dict[str, Any]): # 获取有效的JWT令牌 token = get_valid_token() headers = { 'Authorization': f'Bearer {token}', 'Accept-Encoding': 'gzip' # 我们请求gzip压缩 } url = f"https://{WEATHER_API_HOST}/{endpoint}" try: response = requests.get(url, headers=headers, params=params) # 检查响应状态 if response.status_code != 200: # 如果是401或403,尝试刷新令牌并重试 if response.status_code in [401, 403]: # 强制生成新令牌 new_token = generate_jwt() # 更新请求头 headers['Authorization'] = f'Bearer {new_token}' # 重试请求 response = requests.get(url, headers=headers, params=params) # 如果还是失败,则抛出异常 if response.status_code != 200: raise HTTPException( status_code=response.status_code, detail=f"天气API请求失败: HTTP {response.status_code}" ) else: raise HTTPException( status_code=response.status_code, detail=f"天气API请求失败: HTTP {response.status_code}" ) # 依赖 requests 库自动处理Gzip解压缩,并直接解析JSON # 旧的Gzip处理逻辑已被移除 return response.json() except requests.exceptions.JSONDecodeError as e: # 如果响应不是有效的JSON(即使在解压缩后),则捕获此特定错误 raise HTTPException(status_code=500, detail=f"天气API响应解析失败: 无效的JSON内容 - {str(e)}") except HTTPException: # 重新抛出已捕获的HTTPException,以便FastAPI处理 raise except Exception as e: # 捕获其他潜在错误 raise HTTPException(status_code=500, detail=f"天气API请求时发生未知错误: {str(e)}") @app.get("/city/lookup", response_model=LocationResponse, operation_id="lookup_city", tags=["天气查询"]) async def lookup_city( location: str = Query(..., description="城市名称,如:北京") ): """ 根据城市名称查询位置ID - 返回城市的详细信息和位置ID - 位置ID用于后续天气查询 """ try: data = fetch_weather_api("geo/v2/city/lookup", {"location": location}) return data except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @app.get("/weather/now", response_model=WeatherResponse, operation_id="get_weather_now", tags=["天气查询"]) async def get_weather_now( location: str = Query(..., description="位置ID,如:101010100") ): """ 获取指定位置的实时天气 - 需要提供位置ID - 返回当前天气详情 """ try: data = fetch_weather_api("v7/weather/now", {"location": location}) return data except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @app.post("/weather/by-city", response_model=WeatherResponse, operation_id="get_weather_by_city", tags=["天气查询"]) async def get_weather_by_city( query: WeatherQuery ): """ 一站式查询城市天气 - 只需提供城市名 - 自动查询位置ID并获取天气 """ try: # 先查询城市ID location_data = fetch_weather_api("geo/v2/city/lookup", {"location": query.city}) # 检查是否找到城市 if location_data.get("code") != "200" or not location_data.get("location"): raise HTTPException(status_code=404, detail=f"找不到城市: {query.city}") # 获取第一个匹配城市的ID location_id = location_data["location"][0]["id"] # 查询天气 weather_data = fetch_weather_api("v7/weather/now", {"location": location_id}) return weather_data except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) 3.4.6 主程序及 MCP 集成@app.get("/") async def root(): """主页 - 提供API简介""" return { "message": "天气查询API", "endpoints": [ "/generate-jwt - 生成JWT令牌", "/city/lookup - 根据城市名查询位置ID", "/weather/now - 根据位置ID查询当前天气", "/weather/by-city - 一站式查询城市天气" ], "docs": "/docs 查看完整API文档" } # mcp 实现 mcp = FastApiMCP( app, name="My Weather MCP", description="天气查询API", include_operations=["get_weather_by_city"], # 只公开 get_weather_by_city 接口作为 MCP tool auth_config=AuthConfig(dependencies=[Depends(verify_bearer_token)]) # MCP 使用 Bearer Token 验证 ) mcp.mount() # 启动服务器的命令(在命令行中运行): # uvicorn main:app --reload if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8009) 4. 测试验证4.1 本地服务测试启动服务:python main.pyAPI 文档验证:访问 http://localhost:8009/docs测试各个接口功能验证数据格式正确性我们可以使用浏览器访问 http://localhost:8009/docs 来查看并测试API。4.2 MCP 客户端集成Cherry Studio 配置:服务名称: FastAPI 天气查询连接类型: 服务器发送事件(SSE)服务地址: http://localhost:8009/mcp认证头: Authorization=Bearer huaweicloud功能验证:配置 MCP 服务连接验证工具列表显示测试天气查询功能对比启用前后的效果在 Cherry Studio 中配置好的 MCP 服务,我们可以直接在 MCP 客户端中使用 get_weather_by_city 接口:名称:FastAPI 天气查询类型:服务器发送事件(SSE)URL:http://localhost:8009/mcp请求头:Authorization=Bearer zishu.co在工具中,我们可以看到get_weather_by_city接口已经添加到MCP服务中。新建一个话题,先不开启 MCP 服务器设置,直接输入北京天气怎么样,我们会发现大模型无法实时获取天气。接着我们启用 MCP 服务,并输入北京天气怎么样,我们会发现大模型可以实时获取天气。get_weather_by_city tool 被成功调用,并返回了天气信息。5. 总结5.1 技术收获通过本案例,您将掌握:MCP 协议: 理解 AI 模型与外部工具的交互机制FastAPI 开发: 快速构建高性能 Web APIJWT 认证: 实现安全的 API 访问控制第三方 API 集成: 学会封装和调用外部服务错误处理: 构建健壮的服务应用5.2 应用价值实时数据获取: AI 模型可以获取最新的天气信息用户体验提升: 提供准确、及时的天气查询服务技术架构: 为更复杂的 MCP 应用奠定基础可扩展性: 可以轻松添加更多天气相关功能如果想要拓展更多功能,您可以动手试试看!
-
本案例选择MPI应用来验证展示鲲鹏DevKit的多点并行调试能力以及鲲鹏平台远程编译调试能力。并借助开发者空间云主机提供的CodeArts IDE和鲲鹏服务器进行MPI应用的编译与并行调试,让开发者直观体验鲲鹏DevKit编译调试功能。1 概述1.1 背景介绍鲲鹏DevKit是覆盖软件迁移、应用开发和性能调优的全流程鲲鹏原生开发工具,可以帮助开发者加速应用迁移和算力升级,提供鲲鹏开发套件,包括应用迁移和性能分析等一些列软件工具。通过实际操作,让大家了解如何通过鲲鹏DevKit插件远程连接DevKit工具,并对应用进行远程编译调试,体验鲲鹏DevKit在鲲鹏原生开发过程中给开发者提供的便利。1.2 适用对象企业个人开发者高校学生1.3 案例时间本案例总时长预计120分钟。1.4 案例流程说明:① 自动部署鲲鹏服务器;② 安装鲲鹏DevKit插件;③ 下载MPI程序源文件;④ 环境安装;⑤ 编译应用;⑥ 并行调试。1.5 资源总览本案例预计花费总计0元。资源名称规格单价(元)时长(分钟)云主机2vCPUs4GBX86鲲鹏服务器2vCPUs8GBEulerOS 2.82 操作步骤2.1 自动部署鲲鹏服务器在云主机桌面右键选择“Open Terminal Here”,打开命令终端窗口。执行自动部署命令如下:hcd deploy --password abcd1234@ --time 7200 命令的参数说明:password:password关键字后设置的是鲲鹏服务器的root用户密码,命令中给出的默认为abcd1234@,开发者可以替换成自定义密码(至少8个字符)。time:time关键字后面设置的为鲲鹏服务器的可用时间,单位为秒,至少600秒。本案例建议申请的时间为120分钟,即7200秒。记录部署鲲鹏服务器公网IP,例如截图中对应的就是:1.94.112.100,实际操作时使用个人部署的鲲鹏服务器IP。2.2 安装鲲鹏DevKit插件由于CodeArts IDE在线安装的鲲鹏DevKit工具版本过低,所以需要前往鲲鹏社区官网下载最新鲲鹏DevKit插件到云主机,下载地址为:插件市场。如下图所示,进入到下载页面后选择最新版本进行下载。如果插件市场无法下载或下载失败可直接在浏览器下载。在云主机桌面,打开CodeArts IDE for Python/Java开发环境,单击右侧“扩展”按钮,点击“从本地安装”,选择下载好的插件安装。在弹窗中选择“继续安装”。2.3 下载MPI程序源文件在云主机桌面右键选择“Open Terminal Here”,打开命令终端窗口,输入以下命令下载并解压待使用的MPI程序源文件。wget https://codeload.github.com/kunpengcompute/devkitdemo/zip/refs/heads/devkitdemo-23.0.1 unzip devkitdemo-23.0.1 解压后“Compiler_and_Debugger/mpi_demo/”路径下的bcast_demo.c作为MPI程序源文件。2.4 环境安装以下工具或依赖库安装更新都是在2.1自动部署的鲲鹏服务器上进行的,不是云主机,确定好操作环境再进行安装。使用“ssh root@鲲鹏服务器公网IP”命令连接远程鲲鹏服务器,“鲲鹏服务器公网”就是自动部署鲲鹏服务器后记录的IP地址。2.4.1 安装mpicc由于在自动部署拉起的服务器上进行编译调试时,需要使用mpicc,mpicc是MPI实现的一部分,常见的MPI实现有OpenMPI和MPICH。这里安装OpenMPI。使用ssh命令(ssh root@鲲鹏服务器公网IP)连接远程鲲鹏服务器后,执行以下命令安装OpenMPI。sudo yum update -y sudo yum install -y openmpi openmpi-devel配置环境变量:1.编辑配置文件,进入Vim窗口后,按“i”编辑profile。sudo vim /etc/profile2.在文件末尾添加以下内容。export PATH=\$PATH:/usr/lib64/openmpi/bin3.按“ECS”退出编辑,再按“:wq”保存修改并退出,然后刷新配置文件。source /etc/profile安装 OpenMPI 后会提供 mpicc,查看 mpicc 的版本信息成功,表明 mpicc 已经成功安装在你的系统中。mpicc --version2.4.2 安装MPI由于目前环境中mpirun版本为2.1.1,不满足lldb-server服务要求,需要更新。这里我们安装MPI 4.1.4版本。同样在远程鲲鹏服务器中,下载安装包。mkdir -p /path/to/OpenMPI cd /path/to/OpenMPI wget https://dtse-mirrors.obs.cn-north-4.myhuaweicloud.com/case/0018/openmpi-4.1.4.tar.gz tar -zxvf openmpi-4.1.4.tar.gz安装依赖包。yum install -y numactl-devel-\* systemd-devel-\* 加载编译器。export PATH=/path/to/GUN/bin:\$PATH export LD_LIBRARY_PATH=/path/to/GUN/lib64:\$LD_LIBRARY_PATH 执行以下命令进行配置预编译。cd openmpi-4.1.4 ./configure --prefix=/path/to/OPENMPI --enable-pretty-print-stacktrace --enable-orterun-prefix-by-default --with-cma --enable-mpi1-compatibility CC=gcc CXX=g++ FC=gfortran安装编译。make -j 2 make install配置环境变量:1.编辑配置文件,进入Vim窗口后,按“i”编辑profilesudo vim /etc/profile2.在文件末尾添加export PATH=/path/to/GNU/bin:/path/to/OPENMPI/bin:\$PATH export LD_LIBRARY_PATH=/path/to/GNU/lib64:/path/to/OPENMPI/lib:\$LD_LIBRARY_PATH 3.按“ECS”退出编辑,再按“:wq”保存修改并退出,然后刷新配置文件。source /etc/profile/path/to/OPENMPI/:OpenMPI实际安装的路径,请根据实际情况进行替换。执行以下命令验证OpenMPI是否安装成功。mpirun --version2.4.3 创建libstdc++.so.6软链接由于/usr/lib64/libstdc++.so.6版本较旧,不包含GLIBCXX_3.4.26,不满足lldb-server需求。这里用软链接方式将/usr/lib64/libstdc++.so.6 的链接指向 /opt/Devkit/tools/libstdc++.so.6。建议备份/usr/lib64/libstdc++.so.6。sudo mv /usr/lib64/libstdc++.so.6 /usr/lib64/libstdc++.so.6.bak建立软链接。sudo ln -s /opt/DevKit/tools/libstdc++.so.6 /usr/lib64/libstdc++.so.6 检查软链接。ls -l /usr/lib64/libstdc++.so.6 2.5 编译应用在云主机桌面双击打开CodeArts IDE,打开解压后的MPI程序,即解压后“Compiler_and_Debugger/mpi_demo/”路径。打开工程后,点击打开bcast_demo.c文件,修改85行为:“int color = rankNum / 1;”。即将调试时划分通信子组规则由2个rank为1个通信子组改为1个rank为1个通信子组。进入鲲鹏DevKit插件,选择使用鲲鹏DevKit窗口中的“开始使用”,配置IP和端口,IP是2.1自动部署鲲鹏服务器得到的弹性公网IP,端口是8086,服务证书选择“信任当前服务证书”。首次登录需要创建管理员密码,登录成功后,点击“编译”,添加目标服务器。添加远程鲲鹏服务器为目标服务器,服务器IP地址为鲲鹏服务器弹性公网IP地址。然后再次点击“编译”到编译配置窗口,服务器信息会自动带出,配置编译命令后再点击“编译”。编译命令如下:mpicc -g bcast_demo.c -o bcast_demo首次创建后再修改编译和调试配置可以通过点击CodeArts IDE底部“鲲鹏DevKit”,点击右上角“设置”按钮,再选择 “工程设置”即可对编译和调试配置进行二次修改。根据提示输入鲲鹏服务器密码,编译成功会在鲲鹏服务器/root/workspace/mpi_demo目录下生成带调试信息的可执行文件bcast_demo。2.6 并行调试在DevKit插件中点击“调试”,打开调试页面,选择“HPC并行应用”,配置MPI应用调试参数,点击“开始调试”。应用程序:/root/workspace/mpi_demo/bcast_demo应用程序源码路径:/root/workspace/mpi_demoMPI运行命令行:mpirun --allow-run-as-root -np 2参数说明如下:参数说明远程服务器配置进行HPC并行应用调试的目标服务器Linux用户名输入启动MPI应用的Linux用户名称Linux用户密码使用的Linux用户密码SSH端口驶入启动MPI应用的服务器SSH端口号应用程序输入的MPI应用,支持动态检索并显示应用程序路径应用程序参数(可选)传递给应用程序运行的参数应用程序源码路径源码和MPI应用存放的共享路径,支持动态检索并显示应用程序源码路径。环境变量设置(可选)输入运行HPC并行应用所需要的环境变量调试启动方式调试启动方式可选: mpirun命令运行方式 多瑙调度器运行方式 Slurm调度器运行方式MPI运行命令行输入的mpirun命令以及对应的命令参数,rank数目为1~2048OpenMP应用(可选)勾选后,需要输入OpenMP线程数。死锁检测(可选)勾选后,需要输入死锁超时时间。rank:rank 用于标识 MPI 并行程序中各个进程的唯一编号,在特定通信组内具有唯一性,且决定进程间通信和数据交互的顺序与方式。在 MPI 并行程序执行时,会启动多个进程协同工作,rank 就像是每个进程的 “身份证号”。开始调试后会读取rank状态:在rank状态读取过程中,若rank状态读取全部成功,会自动跳转到MPI应用调试页面。页面上获取到运行和调试区、源码区和调试功能区,运行和调试区域包括调试信息区和rank信息区。HPC并行应用调试支持三种调试粒度,分别为“全部”调试、“rank”调试或“通信组”调试。调用方式效果全部在RANK信息区域选择“全部”方式进行调试,选择某一个rank,对其进行调试会应用到全部rank。rank在RANK信息区域选择“rank”方式进行调试,对单一rank进行调试。通信组在RANK信息区域选择“通信组”方式进行调试,选择通信组中的某一个rank,对其进行调试会应用到整个通信组。调试按钮操作描述:操作操作描述继续点击执行到下一个断点单步跳过点击执行到下一行单步调试点击步入函数单步跳出点击步出函数停止点击后停止调试RANK信息区域选择“全部”调试方式,在89行代码处、47行代码处和93行代码处打上断点,再继续执行后续操作。选择“全部”调试方式,单击“继续”按钮,代码执行到89行,再单击“下一步”执行MPI_Comm_split(MPI_COMM_WORLD, color, rankNum, &row_comm)函数,该函数可将所有的rank进行通信分组。这里将2个rank生成2个通信子组,rank1在通信子组1,rank0在通信子组2。生成2个通信子组后,所有rank的源码执行到90行代码处,选择“通信组”调试方式,选择通信子组1中的rank1,单击“下一步”按钮,通信子组1中的rank代码执行到92行,通信子组2中的rank0代码无变化,停留在90行。调试通信子组1:未调试通信子组2:选择“通信组”调试方式,在左侧通信子组1中选择rank1,单击“继续”按钮,代码执行到47行,单击“下一步”按钮,执行MPI_Barrier(MPI_COMM_WORLD)函数,函数执行完成后,通信子组1会一直处于等待状态,此时,在左侧通信子组2中选择rank0,单击“继续”按钮,代码执行到47行,单击“下一步”按钮,执行MPI_Barrier(MPI_COMM_WORLD)函数,函数执行完成后,通信子组1不再等待,同步执行到49行代码处。rank1处于等待状态:rank0执行后,rank1、rank同步执行到49行:单击“点击放大”按钮,在CodeArts IDE面板中能看到通信子组的变化概览,每100ms显示通信子组的变化。通信子组的变化用不同颜色的菱形来区分,蓝色表示通信子组创建,紫色表示通信子组清除,黄色表示100ms内存在通信子组创建和通信子组清除。释放掉47行断点,RANK信息区域选择“全部”调试方式,循环点击“继续”按钮,代码执行到93行,在单击“下一步”按钮,执行MPI_Comm_free(&row_comm)函数,当不再调试某一通信子组时,可以释放创建的通信子组,该函数能实现释放创建的通信子组。点击侧边或下方工具栏中“运行和调试”查看调试信息。至此,使用鲲鹏DevKit工具进行MPI应用并行调试完成。3 问题记录3.1 编译调试问题1、重复操作案例或更换鲲鹏服务器重新编译失败报错:cd: /root/workspace/mpi_demo: No such file or directory原因:mpi_demo在第一次编译时同步项目到鲲鹏服务器中,并在项目下缓存了记录,想要再次编译时触发同步项目需要删除mpi_demo下的缓存文件。解决:删除云主机中mpi_demo项目下的缓存文件./devkit,删除后重新点击编译,参考2.5编译应用配置编译命令(mpicc -g bcast_demo.c -o bcast_demo)即可。cd /home/developer/Desktop/devkitdemo-devkitdemo-23.0.1/Compiler_and_Debugger/mpi_demo rm -rf .devkit/ “/home/developer/Desktop/devkitdemo-devkitdemo-23.0.1/Compiler_and_Debugger/mpi_demo”是云主机本地mpi_demo路径,以个人操作时实际路径为准。
-
1 概述1.1 背景介绍鲲鹏数学库(KML, Kunpeng Math Library)是基于鲲鹏平台优化的高性能数学函数库,由多个子库组成,广泛应用于科学计算、HPC等领域。 通过本案例,用户可以快速掌握鲲鹏数学库的安装与使用,并对所涉及的数学库性能表现有清晰认识。适用对象1.2 适用对象企业个人开发者高校学生1.3 案例时间本案例总时长预计30分钟。1.4 案例流程说明:① 自动部署并连接鲲鹏服务器;② 安装数学库;③ 修改环境变量;④ 数学库性能测试。1.5 资源总览本次实验预计花费总计0元。资源名称规格单价(元)时长(h)云主机2vCPUs4GB RAM免费0.52 操作步骤2.1 自动部署鲲鹏服务器本实验中,使用云主机提供的鲲鹏沙箱资源,只需要执行简单的自动部署命令即可拉起一台免费的鲲鹏服务器。在云主机桌面右键选择“Open Terminal Here”,打开终端命令窗口。输入自动部署命令,命令如下:hcd deploy --password abcd1234@ --time 1800命令的参数说明:password:password关键字后设置的是鲲鹏服务器的root用户密码,命令中给出的默认为abcd1234@,开发者可以替换成自定义密码(至少8个字符)。time:time关键字后面设置的为鲲鹏服务器的可用时间,单位为秒,至少600秒。当前实验在命令中申请的时间为30分钟,即1800秒。记录下自动部署后生成的鲲鹏服务器公网IP地址。2.2 安装数学库使用命令登录到鲲鹏服务器,命令如下:ssh root@鲲鹏服务器公网IP输入密码,密码为步骤2.1中自动部署命令行中“–password”后面的参数,命令中给出的默认为abcd1234@,如果没有修改,就使用abcd1234@进行登录,如果设置了自定义密码,直接输入自定义的密码(注意:输入过程中密码不会显示,密码输入完成按回车键结束)。使用命令下载数学库软件包,本次案例使用的是1.7.0版本。wget https://repo.oepkgs.net/openeuler/rpm/openEuler-20.03-LTS-SP3/extras/aarch64/Packages/b/boostkit-kml-1.7.0-1.aarch64.rpm解压软件包。rpm2cpio boostkit-kml-1.7.0-1.aarch64.rpm | cpio -div添加软链接,使用ln -s命令创建软链接,类似于Windows中的快捷方式,它是一个特殊的文件,其内容是指向另一个文件或者目录的路径,当访问软链接时,系统会根据软链接中的路径找到实际指向的目标文件或目录来进行操作。下面三组命令分别创建了libkspblas.so、libkvml.so和libkm.so三个软链接,分别指向根据find命令找到对应实际的kspblas.so、kvml.so和km.so文件cp -R /root/usr/local/kml/ /usr/local/cd /usr/local/kmlln -s 'find ./ -name \*kspblas.so\* -type f' ./libkspblas.soln -s 'find ./ -name \*kvml.so\* -type f' ./libkvml.soln -s 'find ./ -name \*km.so\* -type f' ./libkm.so2.3 修改环境变量在 Linux 系统中,LD_LIBRARY_PATH是一个重要的环境变量,它用于指定动态链接库(.so文件)的搜索路径。当程序在运行时需要加载动态链接库,系统会首先在默认的系统库路径中查找,然后会按照LD_LIBRARY_PATH环境变量所指定的路径顺序进行查找。将多个与/usr/local/kml相关的库目录添加到LD_LIBRARY_PATH环境变量中,是因为程序依赖于这些目录下的动态链接库来正确运行。通过将这些目录添加到LD_LIBRARY_PATH,可以确保程序在运行时能够找到所需的库文件。echo 'export LD\_LIBRARY\_PATH=/usr/local/kml/lib/kblas/locking:$LD\_LIBRARY\_PATH' >> /etc/profileecho 'export LD\_LIBRARY\_PATH=/usr/local/kml/lib:$LD\_LIBRARY\_PATH' >> /etc/profileecho 'export LD\_LIBRARY\_PATH=/usr/local/kml/lib/kblas/nolocking:$LD\_LIBRARY\_PATH' >> /etc/profileecho 'export LD\_LIBRARY\_PATH=/usr/local/kml/lib/kblas/omp:$LD\_LIBRARY\_PATH' >> /etc/profileecho 'export LD\_LIBRARY\_PATH=/usr/local/kml/lib/kblas/pthread:$LD\_LIBRARY\_PATH' >> /etc/profileecho 'export LD\_LIBRARY\_PATH=/usr/local/kml/lib/kvml/multi:$LD\_LIBRARY\_PATH' >> /etc/profileecho 'export LD\_LIBRARY\_PATH=/usr/local/kml/lib/kvml/single:$LD\_LIBRARY\_PATH' >> /etc/profileecho 'export LD\_LIBRARY\_PATH=/usr/local/kml/lib/kspblas/multi:$LD\_LIBRARY\_PATH' >> /etc/profileecho 'export LD\_LIBRARY\_PATH=/usr/local/kml/lib/kspblas/single:$LD\_LIBRARY\_PATH' >> /etc/profile执行命令使环境生效。source /etc/profile检查环境变量。env | grep LD\_LIBRARY\_PATH2.4 数学库性能测试1. KML_VML测试矢量数学库(Vector Math Library)借助计算密集型核心数学函数(幂函数、三角函数、指数函数、双曲函数、对数函数等)的矢量实施显著提升应用速度。使用命令创建测试文件test_sin.c文件。cdvi test\_sin.c进入到vim编辑器界面后,按下“i”键后,复制以下代码粘贴到编辑器中,复制完成后按下“ESC”键输入“:wq”,退出编辑器界面,该段代码主要功能是:初始化长度为100000的向量src,分别用计时器对循环使用系统函数库的sin函数求解以及调用KML_VML提供的向量三角函数vdsin求解,记录两种方法的耗时,对比KML_VML与系统函数库的性能。#include <stdio.h>#include <sys/time.h>#include <math.h>#include "kvml.h"#define LEN 100000int main(){ double src\[LEN\] = {0}; double dst1\[LEN\] = {0}; double dst2\[LEN\] = {0}; for(int i = 0; i < LEN; i++){ src\[i\] = i; } struct timeval start, end; long t;gettimeofday(&start, NULL); for(int i = 0; i < LEN; i++){ dst1\[i\] = sin(src\[i\]); }gettimeofday(&end, NULL); t = 100000 \* (end.tv\_sec - start.tv\_sec) + end.tv\_usec - start.tv\_usec; printf("Calculate Time without KML\_VML: %ld us \\n", t);gettimeofday(&start, NULL); vdsin(LEN, src, dst2);gettimeofday(&end, NULL); t = 100000 \* (end.tv\_sec - start.tv\_sec) + end.tv\_usec - start.tv\_usec; printf("Calculate Time with KML\_VML: %ld us \\n", t); return 0;}编译文件, 编译时添加动态库和头文件所在路径,并链接系统数学库和KML_VML动态库。gcc test\_sin.c -o test -L/usr/local/kml/lib/kvml/single -lkvml -lm -I/usr/local/kml/include -fopenmp -std=c99使用ldd指令检查程序依赖库是否准确链接。ldd test执行可执行文件,进行性能对比。./test结果显示,对于一个长度为100000的数组,用C语言的for循环实现求正弦函数值,需要6666微秒,而使用KML_VML仅需要779微秒,性能提升8倍。2. KML_BLAS测试BLAS(Basic Linear Algebra Subprograms)提供了一系列基本线性代数运算函数的标准接口,包括矢量线性组合、矩阵乘以矢量、矩阵乘以矩阵等功能。BLAS已被广泛的应用于工业界和科学计算,成为业界标准。KML_BLAS库提供BLAS函数的C语言接口。使用命令创建测试文件test_gemv.c文件。vi test_gemv.c进入到vim编辑器界面后,按下“i”键后,复制以下代码粘贴到编辑器中,复制完成后按下“ESC”键输入“:wq”,退出编辑器界面,该段代码主要功能是:初始化规模为1000*300的矩阵A,长度为300的向量x,长度为1000的向量y1和y2,分别用计时器对按照矩阵-向量的成家规则实现算法求解,即y=alpha*A*x+beta*y,以及调用KML_BLAS提供的函数cblas_dgemv求解,记录两种方法的耗时,对比KML_BLAS与手动实现矩阵乘加的性能。#include <stdio.h>#include <stdlib.h>#include <time.h>#include <sys/time.h>#include "kblas.h"#define M 1000#define N 300int main() { double alpha = 1.0; double beta = 1.0; double (\*A)\[N\] = (double (\*)\[N\])malloc(M \* N \* sizeof(double)); double \*x = (double \*)malloc(N \* sizeof(double)); double \*y1 = (double \*)malloc(M \* sizeof(double)); double \*y2 = (double \*)malloc(M \* sizeof(double)); srand((unsigned int)time(NULL)); for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { A\[i\]\[j\] = (double)rand() / RAND\_MAX; } } for (int i = 0; i < N; i++) { x\[i\] = (double)rand() / RAND\_MAX; } for (int i = 0; i < M; i++) { y1\[i\] = (double)rand() / RAND\_MAX; y2\[i\] = (double)rand() / RAND\_MAX; } // 方法一:按照矩阵-向量的乘加规则实现算法求解 struct timeval start, end; long t;gettimeofday(&start, NULL);for (int i = 0; i < M; i++) { double sum = 0.0; for (int j = 0; j < N; j++) { sum += A\[i\]\[j\] \* x\[j\]; } y1\[i\] = alpha \* sum + beta \* y1\[i\];}gettimeofday(&end, NULL); t = 100000 \* (end.tv\_sec - start.tv\_sec) + end.tv\_usec - start.tv\_usec; printf("Calculate Time without KML\_BLAS: %ld us \\n", t); // 方法二:调用KML\_BLAS提供的函数cblas\_dgemv求解gettimeofday(&start, NULL); cblas\_dgemv(CblasRowMajor, CblasNoTrans, M, N, alpha, (const double \*)A, N, x, 1, beta, y2, 1);gettimeofday(&end, NULL); t = 100000 \* (end.tv\_sec - start.tv\_sec) + end.tv\_usec - start.tv\_usec; printf("Calculate Time with KML\_BLAS: %ld us \\n", t); return 0;}编译文件,编译时添加动态库和头文件所在路径,并链接KML_BLAS动态库。gcc test\_gemv.c -g -o test2 -L /usr/local/kml/lib/kblas/locking/ -lkblas -I /usr/local/kml/include -std=c99使用ldd指令检查程序依赖库是否准确链接。ldd test2执行可执行文件,进行性能对比。./test2结果显示,计算一个1000*300的矩阵-向量乘加运算,用C语言的for循环实现,需要1904微秒,而使用KML_BLAS仅需要145微秒,性能提升13倍。至此,本次案例体验全部完成。
-
西北赛区从整点变成20了 每次都慢5分钟 是不是代码写的有问题(bushi
-
华为云软件开发生产线CodeArts是一站式、全流程、安全可信的云原生DevSecOps平台,覆盖需求、开发、测试、部署、运维等软件交付全生命周期环节,为开发者打造全云化研发体验。华为云CodeArts目前已上线28款研发工具,服务于300多万开发者,应用于10多个行业,覆盖开发全场景。2025年1月,CodeArts发布了架构建模、CodeArts API相关新特性,具体内容如下: 架构建模 CodeArts Modeling新特性支持UML时间图支持UML类生成Java代码体验优化模型批注状态增加颜色进行区分问题修复修复无法查询元素在关联模型工程中创建关系的问题修复点击面包屑中项目名称跳转到需求管理首页的问题CodeArts API新特性支持上海一regionAPI设计模块支持导出html格式接口文档体验优化项目设置模块导入数据列表支持搜索和排序目前,华为云CodeArts已携手百万级开发者,在政府、物流、金融、教育、制造等10多个行业落地,助力企业构建了敏捷、高效、安全的数字化生产模式。使用华为云CodeArts,中国海油构建了供应链一体化数字化平台,研发工时节省了30%,智能油田管理系统集成、调试、部署时间从1周缩短为1天。中国邮政储蓄银行通过使用华为云CodeArts盘古助手打造智能开发平台,代码生成采纳率超30%,单元测试代码采纳率超60%,已自动生成29万余行高质量代码,高效支持超过200个应用系统的开发,实现了更好的智能化开发体验。未来,华为云CodeArts将积极增强软件开发的全流程智能协同,不断实现智能化创新,提升全流程研发效能,为开发者创造更多的业务价值,促进中国软件生态的繁荣。体验通道:https://www.huaweicloud.com/devcloud/?utm_source=developer.huaweicloud&utm_content=feature
-
写入完成后可以调整已写入内容的位置吗 会不会对导致读取和删除操作出现错误
-
请问本次比赛程序运行总时间是多少
-
【算法挑战营二十一期】为啥测评两天了不出结果?
-
整体log日志内容如下,请问这是什么情况,该怎么解决:2025-01-03 13:40:08【info】usecase0 build start2025-01-03 13:40:10【info】usecase0 build end2025-01-03 13:40:10【info】usecase0 round0 search start【E3:Run Error】选手程序执行中断
-
【云咖问答】第18期 华为云软件开发生产线(CodeArts)新特性解读,专家面对面提问互动赢好礼活动获奖名单如下:优质问题奖郑小健积极互动奖yd_252629448linghz666suifeng1324熊大不大海是岛思念的泪enkileeHello Digger福州司马懿恭喜以上9名开发者获奖,即日起请获奖者查看私信,填写问卷确认获奖信息,反馈截止时间2025年1月14日,18号前发货,逾期未提供有效收件信息,视为放弃活动领奖,感谢大家对华为云论坛的关注和支持~华为云软件开发生产线CodeArts是一站式、全流程、安全可信的云原生DevSecOps平台,覆盖需求、开发、测试、部署、运维等软件交付全生命周期环节,为开发者打造全云化研发体验。华为云CodeArts目前已上线28款研发工具,服务于300多万开发者,应用于10多个行业,覆盖开发全场景。2024年11月,CodeArts发布了需求管理、测试计划、代码托管、部署、开源治理相关新特性,点击查看详情本期我们邀请了华为云高级产品经理苏柏亚培坐阵,和大家一期探讨CodeArts 11月新特性的话题,点击报名预约直播《华为云软件开发生产线(CodeArts)11月新特性解读》,听专家在线面对面讲解,直播时间:2024年12月24日 19:00-20:00。 【本期云咖】 【问题参考】(包括不限于)CodeArts平台上的数据存放在哪里的?怎么保证数据的安全性?IPD项目模板可以免费使用吗?CodeArts支持鸿蒙系统吗?……对于CodeArts,你有哪些疑问呢? 【活动时间】2024年12月20日-2025年1月6日 【参与方式】直接在此活动帖下方回帖提问即可。 【获奖规则】参与云咖问答的提问我们会整理在问答专题中,你的提问将会帮助更多的开发者~欢迎大家踊跃提问,积极互动~ 【活动规则】1、开发者用户发布的提问,必须与本期产品相关,其他产品求助帖不参与此次活动,将视为无效内容,否则取消该用户获奖资格。(其他产品求助可发帖到相应的版块进行提问);2、本次活动不限用户的总提问数及连续提问数,但需保证提问质量,如华为云社区小编认定参与用户有恶意灌水嫌疑,则取消该用户获奖资格;3、本次活动将根据实际参与情况发放奖励,包括但不限于用户百分之百中奖或奖项轮空的情况;以上奖品均为实物奖品,具体发放视出库情况而定; 4、每期活动预计于结束后10天内完成奖项公示,并于结束后30个工作日内完成邮寄。 【温馨提示】1、请务必使用个人实名账号参与活动(IAM、企业账号等账号参与无效)。如一个实名认证对应多个账号,只有一个账号可领取奖励,若同一账号填写多个不同收件人或不同账号填写同一收件人,均不予发放奖励。2、所有获得奖品的获奖用户,请于获奖后3日内完成实名认证,否则视为放弃奖励。
-
开发者空间体验重磅开启:华为面向广大开发者群体,打造的全球开发者专属空间,工具资源预置,成为开发者云上的“家”。本次开发者空间三期活动提供了最新的CodeArts体验案例,一起来探索吧! 【参与形式】Step1:报名开发者空间活动:>活动报名入口<Step2:>免费领取云主机<Step3:有奖调研:参与活动页开发者空间体验,完成调研问卷,即可抽取华为云云宝手办-单个盲盒、开发者定制鼠标垫!礼品参考展示:
-
各位小伙伴久等啦~感谢大家的参与,现公布有奖征文环节获奖名单,请在2月12日前>点此反馈发奖信息<,逾期视为放弃领奖,请耐心等待礼品发放哦~期待小伙伴们持续关注后续更多精彩活动! 【活动原文】【活动简介】年终,作为一个特殊的节点,不仅是回顾过去一年技术发展历程、总结经验教训的时刻,更是展望未来、规划新一年技术路线图的契机。在这样的背景下,针对PaaS开发者,开展一场年终线上福利活动,旨在通过一系列互动活动,与广大开发者们一起回顾一年以来的成长历程,并且希望各位小伙伴能给出一些好的建议和反馈,促进PaaS产品的进步,同时准备了丰厚的福利回馈给大家,欢迎新老用户共同参与!>>>活动报名入口<<<【活动内容速览】Part1:用户回馈:限时优惠购,福利大放送1、产品优惠套餐限时购CodeArts Repo18元套餐(仅面向新注册用户)Astro Zero 5.99元套餐(仅面向新注册用户)CodeArts免费体验版开通开发者空间云主机免费领取2、登录即抽奖,超多丰富礼品在等你!登录报名活动,即可参与抽奖!(奖品:100/50元京东卡、华为自拍杆、半入耳式耳机、鼠标垫、数据线、保温杯、棒球帽、书籍等十多种好礼可抽取!) Part2:有奖征文:开发者成长年度回顾报名活动,根据活动页要求发布文章,筛选优质内容10篇,奖励50元京东卡! Part3:学习体验最佳案例,反馈真实建议1、在线学习:从0到1深度体验华为云CodeArts2、最佳案例体验:凤凰商城DevOps实践Astro Zero零代码构建记账本小程序基于Functiongraph的AI风格化编程一键部署你的AI绘图应用3、有奖调研问卷报名活动,参与填写活动页调研问卷,即可抽奖(奖品:华为云云宝手办*5、鼠标垫*10) 加入PaaS产品交流群,与大家共同进步。
-
QQ测试名额一般什么时侯发放?
上滑加载中
推荐直播
-
用码道,让你的AI作品三步上朋友圈2026/08/04 周二 19:00-20:00
林华鼎-华为云AI开发者运营负责人
从入门 · 到做AI应用 · 到企业级开发。不教编程,只教用AI · 零代码、有产出、能带走、可炫耀 · 每课人人动手实操
回顾中 -
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
基于华为云码道,构建你的定制化AI搭子2026/08/14 周五 09:00-11:30
明亮-华为云开发者发展与支持部部长
本期直播将向您全面介绍华为云码道产品,并基于码道手把手教你部署自己的定制化AI陪伴搭子。
回顾中
热门标签