[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"similar-mratsim--Arraymancer":3,"tool-mratsim--Arraymancer":61},[4,18,26,36,44,53],{"id":5,"name":6,"github_repo":7,"description_zh":8,"stars":9,"difficulty_score":10,"last_commit_at":11,"category_tags":12,"status":17},4358,"openclaw","openclaw\u002Fopenclaw","OpenClaw 是一款专为个人打造的本地化 AI 助手，旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚，能够直接接入你日常使用的各类通讯渠道，包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息，OpenClaw 都能即时响应，甚至支持在 macOS、iOS 和 Android 设备上进行语音交互，并提供实时的画布渲染功能供你操控。\n\n这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地，用户无需依赖云端服务即可享受快速、私密的智能辅助，真正实现了“你的数据，你做主”。其独特的技术亮点在于强大的网关架构，将控制平面与核心助手分离，确保跨平台通信的流畅性与扩展性。\n\nOpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者，以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力（支持 macOS、Linux 及 Windows WSL2），即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你",349277,3,"2026-04-06T06:32:30",[13,14,15,16],"Agent","开发框架","图像","数据工具","ready",{"id":19,"name":20,"github_repo":21,"description_zh":22,"stars":23,"difficulty_score":10,"last_commit_at":24,"category_tags":25,"status":17},3808,"stable-diffusion-webui","AUTOMATIC1111\u002Fstable-diffusion-webui","stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面，旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点，将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。\n\n无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师，还是想要深入探索模型潜力的开发者与研究人员，都能从中获益。其核心亮点在于极高的功能丰富度：不仅支持文生图、图生图、局部重绘（Inpainting）和外绘（Outpainting）等基础模式，还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外，它内置了 GFPGAN 和 CodeFormer 等人脸修复工具，支持多种神经网络放大算法，并允许用户通过插件系统无限扩展能力。即使是显存有限的设备，stable-diffusion-webui 也提供了相应的优化选项，让高质量的 AI 艺术创作变得触手可及。",162132,"2026-04-05T11:01:52",[14,15,13],{"id":27,"name":28,"github_repo":29,"description_zh":30,"stars":31,"difficulty_score":32,"last_commit_at":33,"category_tags":34,"status":17},1381,"everything-claude-code","affaan-m\u002Feverything-claude-code","everything-claude-code 是一套专为 AI 编程助手（如 Claude Code、Codex、Cursor 等）打造的高性能优化系统。它不仅仅是一组配置文件，而是一个经过长期实战打磨的完整框架，旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。\n\n通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能，everything-claude-code 能显著提升 AI 在复杂任务中的表现，帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略，使得模型响应更快、成本更低，同时有效防御潜在的攻击向量。\n\n这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库，还是需要 AI 协助进行安全审计与自动化测试，everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目，它融合了多语言支持与丰富的实战钩子（hooks），让 AI 真正成长为懂上",142651,2,"2026-04-06T23:34:12",[14,13,35],"语言模型",{"id":37,"name":38,"github_repo":39,"description_zh":40,"stars":41,"difficulty_score":32,"last_commit_at":42,"category_tags":43,"status":17},2271,"ComfyUI","Comfy-Org\u002FComfyUI","ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎，专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式，采用直观的节点式流程图界面，让用户通过连接不同的功能模块即可构建个性化的生成管线。\n\n这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景，也能自由组合模型、调整参数并实时预览效果，轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性，不仅支持 Windows、macOS 和 Linux 全平台，还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构，并率先支持 SDXL、Flux、SD3 等前沿模型。\n\n无论是希望深入探索算法潜力的研究人员和开发者，还是追求极致创作自由度的设计师与资深 AI 绘画爱好者，ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能，使其成为当前最灵活、生态最丰富的开源扩散模型工具之一，帮助用户将创意高效转化为现实。",107888,"2026-04-06T11:32:50",[14,15,13],{"id":45,"name":46,"github_repo":47,"description_zh":48,"stars":49,"difficulty_score":32,"last_commit_at":50,"category_tags":51,"status":17},4721,"markitdown","microsoft\u002Fmarkitdown","MarkItDown 是一款由微软 AutoGen 团队打造的轻量级 Python 工具，专为将各类文件高效转换为 Markdown 格式而设计。它支持 PDF、Word、Excel、PPT、图片（含 OCR）、音频（含语音转录）、HTML 乃至 YouTube 链接等多种格式的解析，能够精准提取文档中的标题、列表、表格和链接等关键结构信息。\n\n在人工智能应用日益普及的今天，大语言模型（LLM）虽擅长处理文本，却难以直接读取复杂的二进制办公文档。MarkItDown 恰好解决了这一痛点，它将非结构化或半结构化的文件转化为模型“原生理解”且 Token 效率极高的 Markdown 格式，成为连接本地文件与 AI 分析 pipeline 的理想桥梁。此外，它还提供了 MCP（模型上下文协议）服务器，可无缝集成到 Claude Desktop 等 LLM 应用中。\n\n这款工具特别适合开发者、数据科学家及 AI 研究人员使用，尤其是那些需要构建文档检索增强生成（RAG）系统、进行批量文本分析或希望让 AI 助手直接“阅读”本地文件的用户。虽然生成的内容也具备一定可读性，但其核心优势在于为机器",93400,"2026-04-06T19:52:38",[52,14],"插件",{"id":54,"name":55,"github_repo":56,"description_zh":57,"stars":58,"difficulty_score":10,"last_commit_at":59,"category_tags":60,"status":17},4487,"LLMs-from-scratch","rasbt\u002FLLMs-from-scratch","LLMs-from-scratch 是一个基于 PyTorch 的开源教育项目，旨在引导用户从零开始一步步构建一个类似 ChatGPT 的大型语言模型（LLM）。它不仅是同名技术著作的官方代码库，更提供了一套完整的实践方案，涵盖模型开发、预训练及微调的全过程。\n\n该项目主要解决了大模型领域“黑盒化”的学习痛点。许多开发者虽能调用现成模型，却难以深入理解其内部架构与训练机制。通过亲手编写每一行核心代码，用户能够透彻掌握 Transformer 架构、注意力机制等关键原理，从而真正理解大模型是如何“思考”的。此外，项目还包含了加载大型预训练权重进行微调的代码，帮助用户将理论知识延伸至实际应用。\n\nLLMs-from-scratch 特别适合希望深入底层原理的 AI 开发者、研究人员以及计算机专业的学生。对于不满足于仅使用 API，而是渴望探究模型构建细节的技术人员而言，这是极佳的学习资源。其独特的技术亮点在于“循序渐进”的教学设计：将复杂的系统工程拆解为清晰的步骤，配合详细的图表与示例，让构建一个虽小但功能完备的大模型变得触手可及。无论你是想夯实理论基础，还是为未来研发更大规模的模型做准备",90106,"2026-04-06T11:19:32",[35,15,13,14],{"id":62,"github_repo":63,"name":64,"description_en":65,"description_zh":66,"ai_summary_zh":66,"readme_en":67,"readme_zh":68,"quickstart_zh":69,"use_case_zh":70,"hero_image_url":71,"owner_login":72,"owner_name":73,"owner_avatar_url":74,"owner_bio":75,"owner_company":76,"owner_location":77,"owner_email":78,"owner_twitter":76,"owner_website":76,"owner_url":79,"languages":80,"stars":96,"forks":97,"last_commit_at":98,"license":99,"difficulty_score":100,"env_os":101,"env_gpu":102,"env_ram":103,"env_deps":104,"category_tags":111,"github_topics":113,"view_count":32,"oss_zip_url":76,"oss_zip_packed_at":76,"status":17,"created_at":134,"updated_at":135,"faqs":136,"releases":157},4752,"mratsim\u002FArraymancer","Arraymancer","A fast, ergonomic and portable tensor library in Nim with a deep learning focus for CPU, GPU and embedded devices via OpenMP, Cuda and OpenCL backends","Arraymancer 是一个基于 Nim 语言开发的高性能、易用且可移植的张量（多维数组）库，专为科学计算与深度学习打造。它旨在解决传统方案中速度与开发效率难以兼得的痛点：既拥有接近 C++ 的运行时性能，又凭借 Nim 语言极快的编译速度，让原型开发比 C++ 更加敏捷高效。\n\n该工具支持 CPU、GPU 及嵌入式设备，通过 OpenMP、CUDA 和 OpenCL 后端实现灵活加速，功能覆盖从基础数值计算到机器学习（如分类、回归、聚类）及深度学习的完整生态。其设计灵感源自 Python 社区的 NumPy 和 PyTorch，但提供了更强的类型安全与执行效率。\n\nArraymancer 特别适合追求高性能计算的科研人员、算法工程师以及系统开发者使用。如果你需要在资源受限的嵌入式环境部署模型，或希望在不牺牲执行速度的前提下快速验证复杂的数学算法，这是一个理想选择。此外，它还允许开发者按需组合底层线性代数库（如 BLAS、LAPACK、MKL），为构建定制化的科学计算生态系统提供了坚实基础。","[![Join the chat on Discord #nim-science](https:\u002F\u002Fimg.shields.io\u002Fdiscord\u002F371759389889003530?color=blue&label=nim-science&logo=discord&logoColor=gold&style=flat-square)](https:\u002F\u002Fdiscord.gg\u002Ff5hA9UK3dY) [![Github Actions CI](https:\u002F\u002Fgithub.com\u002Fmratsim\u002Farraymancer\u002Fworkflows\u002FArraymancer%20CI\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fmratsim\u002Farraymancer\u002Factions?query=workflow%3A%Arraymancer+CI%22+branch%3Amaster) [![License](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-Apache%202.0-blue.svg)](https:\u002F\u002Fopensource.org\u002Flicenses\u002FApache-2.0) ![Stability](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fstability-experimental-orange.svg)\n\n# Arraymancer - A n-dimensional tensor (ndarray) library.\n\nArraymancer is a tensor (N-dimensional array) project in Nim. The main focus is providing a fast and ergonomic CPU, Cuda and OpenCL ndarray library on which to build a scientific computing ecosystem.\n\nThe library is inspired by Numpy and PyTorch and targets the following use-cases:\n\n- N-dimensional arrays (tensors) for numerical computing\n- machine learning algorithms (as in Scikit-learn: least squares solvers, PCA and dimensionality reduction, classifiers, regressors and clustering algorithms, cross-validation).\n- deep learning\n\nThe ndarray component can be used without the machine learning and deep learning component.\nIt can also use the OpenMP, Cuda or OpenCL backends.\n\nNote: While Nim is compiled and does not offer an interactive REPL yet (like Jupyter), it allows much faster prototyping than C++ due to extremely fast compilation times. Arraymancer compiles in about 5 seconds on my dual-core MacBook.\n\nReminder of supported compilation flags:\n\n- `-d:release`: Nim release mode (no stacktraces and debugging information)\n- `-d:danger`: No runtime checks like array bound checking\n- `-d:blas=blaslibname`: Customize the BLAS library used by Arraymancer. By default (i.e. if you don't define this setting) Arraymancer will try to automatically find a BLAS library (e.g. `blas.so\u002Fblas.dll` or `libopenblas.dll`) on your path. You should only set this setting if for some reason you want to use a specific BLAS library. See [nimblas](https:\u002F\u002Fgithub.com\u002FSciNim\u002Fnimblas) for further information\n- `-d:lapack=lapacklibname`: Customize the LAPACK library used by Arraymancer. By default (i.e. if you don't define this setting) Arraymancer will try to automatically find a LAPACK library (e.g. `lapack.so\u002Flapack.dll` or `libopenblas.dll`) on your path. You should only set this setting if for some reason you want to use a specific LAPACK library. See [nimlapack](https:\u002F\u002Fgithub.com\u002FSciNim\u002Fnimlapack) for further information\n- `-d:openmp`: Multithreaded compilation\n- `-d:mkl`: Deprecated flag which forces the use of MKL. Implies `-d:openmp`. Use `-d:blas=mkl -d:lapack=mkl` instead, but _only_ if you want to force Arraymancer to use MKL, instead of looking for the available BLAS \u002F LAPACK libraries\n- `-d:openblas`: Deprecated flag which forces the use of OpenBLAS. Use `-d:blas=openblas -d:lapack=openblas` instead, but _only_ if you want to force Arraymancer to use OpenBLAS, instead of looking for the available BLAS \u002F LAPACK libraries\n- `-d:cuda`: Build with Cuda support\n- `-d:cudnn`: Build with CuDNN support, implies `-d:cuda`\n- `-d:avx512`: Build with AVX512 support by supplying the `-mavx512dq` flag\n  to gcc \u002F clang. Without this flag the resulting binary does not use AVX512\n  even on CPUs that support it. Setting this flag, however, makes the binary\n  incompatible with CPUs that do _not_ support AVX512. See the comments in #505\n  for a discussion (from `v0.7.9`)\n- You might want to tune library paths in [nim.cfg](nim.cfg) after installation for OpenBLAS, MKL and Cuda compilation.\n  The current defaults should work on Mac and Linux; and on Windows after downloading `libopenblas.dll` or another\n  BLAS \u002F LAPACK DLL (see the [Installation](#installation) section for more information) and copying it into a folder\n  in your path or into the compilation output folder.\n\n## Show me some code\n\nThe Arraymancer tutorial is available [here](https:\u002F\u002Fmratsim.github.io\u002FArraymancer\u002Ftuto.first_steps.html).\n\nHere is a preview of Arraymancer syntax.\n\n### Tensor creation and slicing\n\n```Nim\nimport math, arraymancer\n\nconst\n    x = @[1, 2, 3, 4, 5]\n    y = @[1, 2, 3, 4, 5]\n\nvar\n    vandermonde = newSeq[seq[int]]()\n    row: seq[int]\n\nfor i, xx in x:\n    row = newSeq[int]()\n    vandermonde.add(row)\n    for j, yy in y:\n        vandermonde[i].add(xx^yy)\n\nlet foo = vandermonde.toTensor()\n\necho foo\n\n# Tensor[system.int] of shape \"[5, 5]\" on backend \"Cpu\"\n# |1          1       1       1       1|\n# |2          4       8      16      32|\n# |3          9      27      81     243|\n# |4         16      64     256    1024|\n# |5         25     125     625    3125|\n\necho foo[1..2, 3..4] # slice\n\n# Tensor[system.int] of shape \"[2, 2]\" on backend \"Cpu\"\n# |16      32|\n# |81     243|\n\necho foo[_|-1, _] # reverse the order of the rows\n\n# Tensor[int] of shape \"[5, 5]\" on backend \"Cpu\"\n# |5      25      125     625     3125|\n# |4      16       64     256     1024|\n# |3       9       27      81      243|\n# |2       4        8      16       32|\n# |1       1        1       1        1|\n```\n\n### Reshaping and concatenation\n\n```Nim\nimport arraymancer, sequtils\n\nlet a = toSeq(1..4).toTensor.reshape(2,2)\n\nlet b = toSeq(5..8).toTensor.reshape(2,2)\n\nlet c = toSeq(11..16).toTensor\nlet c0 = c.reshape(3,2)\nlet c1 = c.reshape(2,3)\n\necho concat(a,b,c0, axis = 0)\n# Tensor[system.int] of shape \"[7, 2]\" on backend \"Cpu\"\n# |1      2|\n# |3      4|\n# |5      6|\n# |7      8|\n# |11    12|\n# |13    14|\n# |15    16|\n\necho concat(a,b,c1, axis = 1)\n# Tensor[system.int] of shape \"[2, 7]\" on backend \"Cpu\"\n# |1      2     5     6    11    12    13|\n# |3      4     7     8    14    15    16|\n```\n\n### Broadcasting\n\nImage from Scipy\n\n![](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fmratsim_Arraymancer_readme_0796c79df782.gif)\n\n```Nim\nimport arraymancer\n\nlet j = [0, 10, 20, 30].toTensor.reshape(4,1)\nlet k = [0, 1, 2].toTensor.reshape(1,3)\n\necho j +. k\n# Tensor[system.int] of shape \"[4, 3]\" on backend \"Cpu\"\n# |0      1     2|\n# |10    11    12|\n# |20    21    22|\n# |30    31    32|\n```\n\n### A simple two layers neural network\n\nFrom [example 3](.\u002Fexamples\u002Fex03_simple_two_layers.nim).\n\n```Nim\nimport arraymancer, strformat\n\ndiscard \"\"\"\nA fully-connected ReLU network with one hidden layer, trained to predict y from x\nby minimizing squared Euclidean distance.\n\"\"\"\n\n# ##################################################################\n# Environment variables\n\n# N is batch size; D_in is input dimension;\n# H is hidden dimension; D_out is output dimension.\nlet (N, D_in, H, D_out) = (64, 1000, 100, 10)\n\n# Create the autograd context that will hold the computational graph\nlet ctx = newContext Tensor[float32]\n\n# Create random Tensors to hold inputs and outputs, and wrap them in Variables.\nlet\n  x = ctx.variable(randomTensor[float32](N, D_in, 1'f32))\n  y = randomTensor[float32](N, D_out, 1'f32)\n\n# ##################################################################\n# Define the model\n\nnetwork TwoLayersNet:\n  layers:\n    fc1: Linear(D_in, H)\n    fc2: Linear(H, D_out)\n  forward x:\n    x.fc1.relu.fc2\n\nlet\n  model = ctx.init(TwoLayersNet)\n  optim = model.optimizer(SGD, learning_rate = 1e-4'f32)\n\n# ##################################################################\n# Training\n\nfor t in 0 ..\u003C 500:\n  let\n    y_pred = model.forward(x)\n    loss = y_pred.mse_loss(y)\n\n  echo &\"Epoch {t}: loss {loss.value[0]}\"\n\n  loss.backprop()\n  optim.update()\n```\n\n### Teaser A text generated with Arraymancer's recurrent neural network\n\nFrom [example 6](.\u002Fexamples\u002Fex06_shakespeare_generator.nim).\n\nTrained 45 min on my laptop CPU on Shakespeare and producing 4000 characters\n\n```\nWhter!\nTake's servant seal'd, making uponweed but rascally guess-boot,\nBare them be that been all ingal to me;\nYour play to the see's wife the wrong-pars\nWith child of queer wretchless dreadful cold\nCursters will how your part? I prince!\nThis is time not in a without a tands:\nYou are but foul to this.\nI talk and fellows break my revenges, so, and of the hisod\nAs you lords them or trues salt of the poort.\n\nROMEO:\nThou hast facted to keep thee, and am speak\nOf them; she's murder'd of your galla?\n\n# [...] See example 6 for full text generation samples\n```\n\n## Table of Contents\n\u003C!-- TOC -->\n\n- [Arraymancer - A n-dimensional tensor (ndarray) library.](#arraymancer---a-n-dimensional-tensor-ndarray-library)\n  - [Show me some code](#show-me-some-code)\n    - [Tensor creation and slicing](#tensor-creation-and-slicing)\n    - [Reshaping and concatenation](#reshaping-and-concatenation)\n    - [Broadcasting](#broadcasting)\n    - [A simple two layers neural network](#a-simple-two-layers-neural-network)\n    - [Teaser A text generated with Arraymancer's recurrent neural network](#teaser-a-text-generated-with-arraymancers-recurrent-neural-network)\n  - [Table of Contents](#table-of-contents)\n  - [Installation](#installation)\n  - [Full documentation](#full-documentation)\n  - [Features](#features)\n    - [Arraymancer as a Deep Learning library](#arraymancer-as-a-deep-learning-library)\n      - [Fizzbuzz with fully-connected layers (also called Dense, Affine or Linear layers)](#fizzbuzz-with-fully-connected-layers-also-called-dense-affine-or-linear-layers)\n      - [Handwritten digit recognition with convolutions](#handwritten-digit-recognition-with-convolutions)\n      - [Sequence classification with stacked Recurrent Neural Networks](#sequence-classification-with-stacked-recurrent-neural-networks)\n    - [Tensors on CPU, on Cuda and OpenCL](#tensors-on-cpu-on-cuda-and-opencl)\n  - [What's new in Arraymancer v0.5.1 - July 2019](#whats-new-in-arraymancer-v051---july-2019)\n  - [4 reasons why Arraymancer](#4-reasons-why-arraymancer)\n    - [The Python community is struggling to bring Numpy up-to-speed](#the-python-community-is-struggling-to-bring-numpy-up-to-speed)\n    - [A researcher workflow is a fight against inefficiencies](#a-researcher-workflow-is-a-fight-against-inefficiencies)\n    - [Can be distributed almost dependency free](#can-be-distributed-almost-dependency-free)\n    - [Bridging the gap between deep learning research and production](#bridging-the-gap-between-deep-learning-research-and-production)\n    - [So why Arraymancer ?](#so-why-arraymancer-)\n  - [Future ambitions](#future-ambitions)\n\n\u003C!-- \u002FTOC -->\n\n## Installation\n\nNim is available in some Linux repositories and on Homebrew for macOS.\n\nI however recommend installing Nim in your user profile via [``choosenim``](https:\u002F\u002Fgithub.com\u002Fdom96\u002Fchoosenim). Once choosenim installed Nim, you can `nimble install arraymancer` which will pull the latest arraymancer release and all its dependencies.\n\nTo install Arraymancer development version you can use `nimble install arraymancer@#head`.\n\nArraymancer requires a BLAS and a LAPACK library.\n\n- On Windows you can get the [OpenBLAS](https:\u002F\u002Fwww.openblas.net) library, which combines BLAS and LAPACK into a single DLL (`libopenblas.dll`), from the binary packages section of the OpenBLAS web page. Alternatively you can download separate BLAS and LAPACK libraries from the [LAPACK for Windows](https:\u002F\u002Ficl.cs.utk.edu\u002Flapack-for-windows\u002Flapack\u002F) site. You must then copy or extract those DLLs into a folder on your path or into the folder containing your compilation target.\n- On MacOS, Apple Accelerate Framework is included in all MacOS versions and provides those.\n- On Linux, you can download libopenblas and liblapack through your package manager.\n\nWindows users may have to download `libopenblas.dll` from the binary releases\n  section of [openblas](https:\u002F\u002Fwww.openblas.net), extract it to the compilation\n\n## Full documentation\n\nDetailed API is available at Arraymancer official [documentation](https:\u002F\u002Fmratsim.github.io\u002FArraymancer\u002F). Note: This documentation is only generated for 0.X release. Check the [examples folder](examples\u002F) for the latest devel evolutions.\n\n## Features\n\nFor now Arraymancer is mostly at the multidimensional array stage, in particular Arraymancer offers the following:\n\n- Basic math operations generalized to tensors (sin, cos, ...)\n- Matrix algebra primitives: Matrix-Matrix, Matrix-Vector multiplication.\n- Easy and efficient slicing including with ranges and steps.\n- No need to worry about \"vectorized\" operations.\n- Broadcasting support. Unlike Numpy it is explicit, you just need to use `+.` instead of `+`.\n- Plenty of reshaping operations: concat, reshape, split, chunk, permute, transpose.\n- Supports tensors of up to 6 dimensions. For example a stack of 4 3D RGB minifilms of 10 seconds would be 6 dimensions:\n  `[4, 10, 3, 64, 1920, 1080]` for `[nb_movies, time, colors, depth, height, width]`\n- Can read and write .csv, Numpy (.npy) and HDF5 files.\n- OpenCL and Cuda backed tensors (not as feature packed as CPU tensors at the moment).\n- Covariance matrices.\n- Eigenvalues and Eigenvectors decomposition.\n- Least squares solver.\n- K-means and PCA (Principal Component Analysis).\n\n### Arraymancer as a Deep Learning library\n\nDeep learning features can be explored but are considered unstable while I iron out their final interface.\n\nReminder: The final interface is still **work in progress.**\n\nYou can also watch the following animated [neural network demo](https:\u002F\u002Fgithub.com\u002FVindaar\u002FNeuralNetworkLiveDemo) which shows live training via [nim-plotly](https:\u002F\u002Fgithub.com\u002Fbrentp\u002Fnim-plotly).\n\n#### Fizzbuzz with fully-connected layers (also called Dense, Affine or Linear layers)\n\nNeural network definition extracted from [example 4](examples\u002Fex04_fizzbuzz_interview_cheatsheet.nim).\n\n```Nim\nimport arraymancer\n\nconst\n  NumDigits = 10\n  NumHidden = 100\n\nnetwork FizzBuzzNet:\n  layers:\n    hidden: Linear(NumDigits, NumHidden)\n    output: Linear(NumHidden, 4)\n  forward x:\n    x.hidden.relu.output\n\nlet\n  ctx = newContext Tensor[float32]\n  model = ctx.init(FizzBuzzNet)\n  optim = model.optimizer(SGD, 0.05'f32)\n# ....\necho answer\n# @[\"1\", \"2\", \"fizz\", \"4\", \"buzz\", \"6\", \"7\", \"8\", \"fizz\", \"10\",\n#   \"11\", \"12\", \"13\", \"14\", \"15\", \"16\", \"17\", \"fizz\", \"19\", \"buzz\",\n#   \"fizz\", \"22\", \"23\", \"24\", \"buzz\", \"26\", \"fizz\", \"28\", \"29\", \"30\",\n#   \"31\", \"32\", \"fizz\", \"34\", \"buzz\", \"36\", \"37\", \"38\", \"39\", \"40\",\n#   \"41\", \"fizz\", \"43\", \"44\", \"fizzbuzz\", \"46\", \"47\", \"fizz\", \"49\", \"50\",\n#   \"fizz\", \"52\",\"53\", \"54\", \"buzz\", \"56\", \"fizz\", \"58\", \"59\", \"fizzbuzz\",\n#   \"61\", \"62\", \"63\", \"64\", \"buzz\", \"fizz\", \"67\", \"68\", \"fizz\", \"buzz\",\n#   \"71\", \"fizz\", \"73\", \"74\", \"75\", \"76\", \"77\",\"fizz\", \"79\", \"buzz\",\n#   \"fizz\", \"82\", \"83\", \"fizz\", \"buzz\", \"86\", \"fizz\", \"88\", \"89\", \"90\",\n#   \"91\", \"92\", \"fizz\", \"94\", \"buzz\", \"fizz\", \"97\", \"98\", \"fizz\", \"buzz\"]\n```\n\n#### Handwritten digit recognition with convolutions\n\nNeural network definition extracted from [example 2](examples\u002Fex02_handwritten_digits_recognition.nim).\n\n```Nim\nimport arraymancer\n\nnetwork DemoNet:\n  layers:\n    cv1:        Conv2D(@[1, 28, 28], out_channels = 20, kernel_size = (5, 5))\n    mp1:        Maxpool2D(cv1.out_shape, kernel_size = (2,2), padding = (0,0), stride = (2,2))\n    cv2:        Conv2D(mp1.out_shape, out_channels = 50, kernel_size = (5, 5))\n    mp2:        MaxPool2D(cv2.out_shape, kernel_size = (2,2), padding = (0,0), stride = (2,2))\n    fl:         Flatten(mp2.out_shape)\n    hidden:     Linear(fl.out_shape[0], 500)\n    classifier: Linear(500, 10)\n  forward x:\n    x.cv1.relu.mp1.cv2.relu.mp2.fl.hidden.relu.classifier\n\nlet\n  ctx = newContext Tensor[float32] # Autograd\u002Fneural network graph\n  model = ctx.init(DemoNet)\n  optim = model.optimizer(SGD, learning_rate = 0.01'f32)\n\n# ...\n# Accuracy over 90% in a couple minutes on a laptop CPU\n```\n\n#### Sequence classification with stacked Recurrent Neural Networks\n\nNeural network definition extracted [example 5](examples\u002Fex05_sequence_classification_GRU.nim).\n\n```Nim\nimport arraymancer\n\nconst\n  HiddenSize = 256\n  Layers = 4\n  BatchSize = 512\n\n\nnetwork TheGreatSequencer:\n  layers:\n    gru1: GRULayer(1, HiddenSize, 4) # (num_input_features, hidden_size, stacked_layers)\n    fc1: Linear(HiddenSize, 32)                  # 1 classifier per GRU layer\n    fc2: Linear(HiddenSize, 32)\n    fc3: Linear(HiddenSize, 32)\n    fc4: Linear(HiddenSize, 32)\n    classifier: Linear(32 * 4, 3)                # Stacking a classifier which learns from the other 4\n  forward x, hidden0:\n    let\n      (output, hiddenN) = gru1(x, hidden0)\n      clf1 = hiddenN[0, _, _].squeeze(0).fc1.relu\n      clf2 = hiddenN[1, _, _].squeeze(0).fc2.relu\n      clf3 = hiddenN[2, _, _].squeeze(0).fc3.relu\n      clf4 = hiddenN[3, _, _].squeeze(0).fc4.relu\n\n    # Concat all\n    # Since concat backprop is not implemented we cheat by stacking\n    # Then flatten\n    result = stack(clf1, clf2, clf3, clf4, axis = 2)\n    result = classifier(result.flatten)\n\n# Allocate the model\nlet\n  ctx = newContext Tensor[float32]\n  model = ctx.init(TheGreatSequencer)\n  optim = model.optimizer(SGD, 0.01'f32)\n\n# ...\nlet exam = ctx.variable([\n    [float32 0.10, 0.20, 0.30], # increasing\n    [float32 0.10, 0.90, 0.95], # increasing\n    [float32 0.45, 0.50, 0.55], # increasing\n    [float32 0.10, 0.30, 0.20], # non-monotonic\n    [float32 0.20, 0.10, 0.30], # non-monotonic\n    [float32 0.98, 0.97, 0.96], # decreasing\n    [float32 0.12, 0.05, 0.01], # decreasing\n    [float32 0.95, 0.05, 0.07]  # non-monotonic\n  ])\n# ...\necho answer.unsqueeze(1)\n# Tensor[ex05_sequence_classification_GRU.SeqKind] of shape [8, 1] of type \"SeqKind\" on backend \"Cpu\"\n# \t  Increasing|\n# \t  Increasing|\n# \t  Increasing|\n# \t  NonMonotonic|\n# \t  NonMonotonic|\n# \t  Increasing| \u003C----- Wrong!\n# \t  Decreasing|\n# \t  NonMonotonic|\n```\n\n#### Composing models\n\nNetwork models can also act as layers in other network definitions.\nThe handwritten-digit-recognition model above can also be written like this:\n\n```Nim\nimport arraymancer\n\nnetwork SomeConvNet:\n  layers h, w:\n    cv1:        Conv2D(@[1, h, w], 20, (5, 5))\n    mp1:        Maxpool2D(cv1.out_shape, (2,2), (0,0), (2,2))\n    cv2:        Conv2D(mp1.out_shape, 50, (5, 5))\n    mp2:        MaxPool2D(cv2.out_shape, (2,2), (0,0), (2,2))\n    fl:         Flatten(mp2.out_shape)\n  forward x:\n    x.cv1.relu.mp1.cv2.relu.mp2.fl\n\n# this model could be initialized like this: let model = ctx.init(SomeConvNet, h = 28, w = 28)\n\n# functions `out_shape` and `in_shape` returning a `seq[int]` are convention (but not strictly necessary)\n# for layers\u002Fmodels that have clearly defined output and input size\nproc out_shape*[T](self: SomeConvNet[T]): seq[int] =\n  self.fl.out_shape\nproc in_shape*[T](self: SomeConvNet[T]): seq[int] =\n  self.cv1.in_shape\n\nnetwork DemoNet:\n  layers:\n  # here we use the previously defined SomeConvNet as a layer\n    cv:         SomeConvNet(28, 28)\n    hidden:     Linear(cv.out_shape[0], 500)\n    classifier: Linear(hidden.out_shape[0], 10)\n  forward x:\n    x.cv.hidden.relu.classifier\n```\n\n#### Custom layers\n\nIt is also possible to create fully custom layers.\nThe documentation for this can be found in the [official API documentation](https:\u002F\u002Fmratsim.github.io\u002FArraymancer\u002Fnn_dsl.html).\n\n### Tensors on CPU, on Cuda and OpenCL\n\nTensors, CudaTensors and CLTensors do not have the same features implemented yet.\nAlso CudaTensors and CLTensors can only be float32 or float64 while CpuTensors can be integers, string, boolean or any custom object.\n\nHere is a comparative table of the core features.\n\n| Action                                            | Tensor                      | CudaTensor                 | ClTensor                   |\n| ------------------------------------------------- | --------------------------- | -------------------------- | -------------------------- |\n| Accessing tensor properties                       | [x]                         | [x]                        | [x]                        |\n| Tensor creation                                   | [x]                         | by converting a cpu Tensor | by converting a cpu Tensor |\n| Accessing or modifying a single value             | [x]                         | []                         | []                         |\n| Iterating on a Tensor                             | [x]                         | []                         | []                         |\n| Slicing a Tensor                                  | [x]                         | [x]                        | [x]                        |\n| Slice mutation `a[1,_] = 10`                      | [x]                         | []                         | []                         |\n| Comparison `==`                                   | [x]                         | []                         | []                         |\n| Element-wise basic operations                     | [x]                         | [x]                        | [x]                        |\n| Universal functions                               | [x]                         | []                         | []                         |\n| Automatically broadcasted operations              | [x]                         | [x]                        | [x]                        |\n| Matrix-Matrix and Matrix-Vector multiplication    | [x]                         | [x]                        | [x]                        |\n| Displaying a tensor                               | [x]                         | [x]                        | [x]                        |\n| Higher-order functions (map, apply, reduce, fold) | [x]                         | internal only              | internal only              |\n| Transposing                                       | [x]                         | [x]                        | []                         |\n| Converting to contiguous                          | [x]                         | [x]                        | []                         |\n| Reshaping                                         | [x]                         | [x]                        | []                         |\n| Explicit broadcast                                | [x]                         | [x]                        | [x]                        |\n| Permuting dimensions                              | [x]                         | []                         | []                         |\n| Concatenating tensors along existing dimension    | [x]                         | []                         | []                         |\n| Squeezing singleton dimension                     | [x]                         | [x]                        | []                         |\n| Slicing + squeezing                               | [x]                         | []                         | []                         |\n\n## What's new in Arraymancer\n\nThe full changelog is available in [changelog.md](.\u002Fchangelog.md).\n\n## 4 reasons why Arraymancer\n\n### The Python community is struggling to bring Numpy up-to-speed\n\n- Numba JIT compiler\n- Dask delayed parallel computation graph\n- Cython to ease numerical computations in Python\n- Due to the GIL shared-memory parallelism (OpenMP) is not possible in pure Python\n- Use \"vectorized operations\" (i.e. don't use for loops in Python)\n\nWhy not use in a single language with all the blocks to build the most efficient scientific computing library with Python ergonomics.\n\nOpenMP batteries included.\n\n### A researcher workflow is a fight against inefficiencies\n\nResearchers in a heavy scientific computing domain often have the following workflow: Mathematica\u002FMatlab\u002FPython\u002FR (prototyping) -> C\u002FC++\u002FFortran (speed, memory)\n\nWhy not use in a language as productive as Python and as fast as C? Code once, and don't spend months redoing the same thing at a lower level.\n\n### Can be distributed almost dependency free\n\nArraymancer models can be packaged in a self-contained binary that only depends on a BLAS library like OpenBLAS, MKL or Apple Accelerate (present on all Mac and iOS).\n\nThis means that there is no need to install a huge library or language ecosystem to use Arraymancer. This also makes it naturally suitable for resource-constrained devices like mobile phones and Raspberry Pi.\n\n### Bridging the gap between deep learning research and production\n\nThe deep learning frameworks are currently in two camps:\n\n- Research: Theano, Tensorflow, Keras, Torch, PyTorch\n- Production: Caffe, Darknet, (Tensorflow)\n\nFurthermore, Python preprocessing steps, unless using OpenCV, often needs a custom implementation (think text\u002Fspeech preprocessing on phones).\n\n- Managing and deploying Python (2.7, 3.5, 3.6) and packages version in a robust manner requires devops-fu (virtualenv, Docker, ...)\n- Python data science ecosystem does not run on embedded devices (Nvidia Tegra\u002Fdrones) or mobile phones, especially preprocessing dependencies.\n- Tensorflow is supposed to bridge the gap between research and production but its syntax and ergonomics are a pain to work with. Like for researchers, you need to code twice, \"Prototype in Keras, and when you need low-level --> Tensorflow\".\n- Deployed models are static, there is no interface to add a new observation\u002Ftraining sample to any framework, what if you want to use a model as a webservice with online learning?\n\n[Relevant XKCD from Apr 30, 2018](https:\u002F\u002Fxkcd.com\u002F1987\u002F)\n\n![Python environment mess](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fmratsim_Arraymancer_readme_79d99e8fcde8.png)\n\n### So why Arraymancer ?\n\nAll those pain points may seem like a huge undertaking however thanks to the Nim language, we can have Arraymancer:\n\n- Be as fast as C\n- Accelerated routines with Intel MKL\u002FOpenBLAS or even NNPACK\n- Access to CUDA and CuDNN and generate custom CUDA kernels on the fly via metaprogramming.\n- Almost dependency free distribution (BLAS library)\n- A Python-like syntax with custom operators `a * b` for tensor multiplication instead of `a.dot(b)` (Numpy\u002FTensorflow) or `a.mm(b)` (Torch)\n- Numpy-like slicing ergonomics `t[0..4, 2..10|2]`\n- For everything that Nim doesn't have yet, you can use Nim bindings to C, C++, Objective-C or Javascript to bring it to Nim. Nim also has unofficial Python->Nim and Nim->Python wrappers.\n\n## Future ambitions\n\nBecause apparently to be successful you need a vision, I would like Arraymancer to be:\n\n- The go-to tool for Deep Learning video processing. I.e. `vid = load_video(\".\u002Fcats\u002Fyoutube_cat_video.mkv\")`\n- Target javascript, WebAssembly, Apple Metal, ARM devices, AMD Rocm, OpenCL, you name it.\n- The base of a Starcraft II AI bot.\n- Target cryptominers FPGAs because they drove the price of GPUs for honest deep-learners too high.\n","[![加入Discord #nim-science聊天](https:\u002F\u002Fimg.shields.io\u002Fdiscord\u002F371759389889003530?color=blue&label=nim-science&logo=discord&logoColor=gold&style=flat-square)](https:\u002F\u002Fdiscord.gg\u002Ff5hA9UK3dY) [![Github Actions CI](https:\u002F\u002Fgithub.com\u002Fmratsim\u002Farraymancer\u002Fworkflows\u002FArraymancer%20CI\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fmratsim\u002Farraymancer\u002Factions?query=workflow%3A%Arraymancer+CI%22+branch%3Amaster) [![License](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-Apache%202.0-blue.svg)](https:\u002F\u002Fopensource.org\u002Flicenses\u002FApache-2.0) ![Stability](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fstability-experimental-orange.svg)\n\n# Arraymancer - 一个N维张量（ndarray）库。\n\nArraymancer是用Nim编写的张量（N维数组）项目。其主要目标是提供一个快速且易用的CPU、Cuda和OpenCL ndarray库，以此为基础构建科学计算生态系统。\n该库受到NumPy和PyTorch的启发，适用于以下场景：\n\n- 用于数值计算的N维数组（张量）\n- 机器学习算法（如Scikit-learn中的最小二乘法求解器、PCA与降维、分类器、回归器和聚类算法、交叉验证等）\n- 深度学习\n\nndarray组件可以独立于机器学习和深度学习部分使用。它还支持OpenMP、Cuda或OpenCL后端。\n\n注意：虽然Nim是编译型语言，目前尚不提供像Jupyter那样的交互式REPL，但由于其极快的编译速度，相比C++能够实现更快的原型开发。在我双核MacBook上，Arraymancer大约5秒即可完成编译。\n\n支持的编译标志说明：\n\n- `-d:release`：Nim发布模式（无堆栈跟踪和调试信息）\n- `-d:danger`：禁用运行时检查，如数组越界检查\n- `-d:blas=blaslibname`：自定义Arraymancer使用的BLAS库。默认情况下（即未设置此选项时），Arraymancer会尝试在系统路径中自动查找BLAS库（例如`blas.so\u002Fblas.dll`或`libopenblas.dll`）。只有在需要使用特定BLAS库时才应设置此选项。更多信息请参见[nimblas](https:\u002F\u002Fgithub.com\u002FSciNim\u002Fnimblas)\n- `-d:lapack=lapacklibname`：自定义Arraymancer使用的LAPACK库。默认情况下（即未设置此选项时），Arraymancer会尝试在系统路径中自动查找LAPACK库（例如`lapack.so\u002Flapack.dll`或`libopenblas.dll`）。只有在需要使用特定LAPACK库时才应设置此选项。更多信息请参见[nimlapack](https:\u002F\u002Fgithub.com\u002FSciNim\u002Fnimlapack)\n- `-d:openmp`：多线程编译\n- `-d:mkl`：已弃用的标志，强制使用MKL。同时隐含`-d:openmp`。建议改用`-d:blas=mkl -d:lapack=mkl`，但仅当您希望强制Arraymancer使用MKL而非自动查找可用的BLAS\u002FLAPACK库时才适用。\n- `-d:openblas`：已弃用的标志，强制使用OpenBLAS。建议改用`-d:blas=openblas -d:lapack=openblas`，但仅当您希望强制Arraymancer使用OpenBLAS而非自动查找可用的BLAS\u002FLAPACK库时才适用。\n- `-d:cuda`：启用Cuda支持进行编译\n- `-d:cudnn`：启用CuDNN支持，同时隐含`-d:cuda`\n- `-d:avx512`：通过向gcc\u002Fclang传递`-mavx512dq`标志来启用AVX512支持。若不使用此标志，即使CPU支持AVX512，生成的二进制文件也不会利用该指令集。然而，启用此标志会使二进制文件无法在不支持AVX512的CPU上运行。相关讨论请参见#505（来自`v0.7.9`版本）。\n- 安装完成后，您可能需要调整[nim.cfg](nim.cfg)中的库路径，以便进行OpenBLAS、MKL和Cuda编译。\n当前的默认设置在Mac和Linux上应该可以正常工作；而在Windows上，则需下载`libopenblas.dll`或其他BLAS\u002FLAPACK DLL（详见“安装”章节），并将其复制到系统路径中的某个文件夹或编译输出目录中。\n\n## 给我看看代码吧\n\nArraymancer教程可在[这里](https:\u002F\u002Fmratsim.github.io\u002FArraymancer\u002Ftuto.first_steps.html)找到。\n\n以下是Arraymancer语法的一个预览。\n\n### 张量创建与切片\n\n```Nim\nimport math, arraymancer\n\nconst\n    x = @[1, 2, 3, 4, 5]\n    y = @[1, 2, 3, 4, 5]\n\nvar\n    vandermonde = newSeq[seq[int]]()\n    row: seq[int]\n\nfor i, xx in x:\n    row = newSeq[int]()\n    vandermonde.add(row)\n    for j, yy in y:\n        vandermonde[i].add(xx^yy)\n\nlet foo = vandermonde.toTensor()\n\necho foo\n\n# Tensor[system.int] of shape \"[5, 5]\" on backend \"Cpu\"\n# |1          1       1       1       1|\n# |2          4       8      16      32|\n# |3          9      27      81     243|\n# |4         16      64     256    1024|\n# |5         25     125     625    3125|\n\necho foo[1..2, 3..4] # slice\n\n# Tensor[system.int] of shape \"[2, 2]\" on backend \"Cpu\"\n# |16      32|\n# |81     243|\n\necho foo[_|-1, _] # reverse the order of the rows\n\n# Tensor[int] of shape \"[5, 5]\" on backend \"Cpu\"\n# |5      25      125     625     3125|\n# |4      16       64     256     1024|\n# |3       9       27      81      243|\n# |2       4        8      16       32|\n# |1       1        1       1        1|\n```\n\n### 重塑与拼接\n\n```Nim\nimport arraymancer, sequtils\n\nlet a = toSeq(1..4).toTensor.reshape(2,2)\n\nlet b = toSeq(5..8).toTensor.reshape(2,2)\n\nlet c = toSeq(11..16).toTensor\nlet c0 = c.reshape(3,2)\nlet c1 = c.reshape(2,3)\n\necho concat(a,b,c0, axis = 0)\n# Tensor[system.int] of shape \"[7, 2]\" on backend \"Cpu\"\n# |1      2|\n# |3      4|\n# |5      6|\n# |7      8|\n# |11    12|\n# |13    14|\n# |15    16|\n\necho concat(a,b,c1, axis = 1)\n# Tensor[system.int] of shape \"[2, 7]\" on backend \"Cpu\"\n# |1      2     5     6    11    12    13|\n# |3      4     7     8    14    15    16|\n```\n\n### 广播\n\n图片来自Scipy\n\n![](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fmratsim_Arraymancer_readme_0796c79df782.gif)\n\n```Nim\nimport arraymancer\n\nlet j = [0, 10, 20, 30].toTensor.reshape(4,1)\nlet k = [0, 1, 2].toTensor.reshape(1,3)\n\necho j +. k\n# Tensor[system.int] of shape \"[4, 3]\" on backend \"Cpu\"\n# |0      1     2|\n# |10    11    12|\n# |20    21    22|\n# |30    31    32|\n```\n\n### 一个简单的两层神经网络\n\n摘自[示例3](.\u002Fexamples\u002Fex03_simple_two_layers.nim)。\n\n```Nim\nimport arraymancer, strformat\n\ndiscard \"\"\"\n一个具有单个隐藏层的全连接ReLU网络，通过最小化欧几里得距离的平方来训练预测y从x。\n\"\"\"\n\n# ##################################################################\n# 环境变量\n\n# N是批量大小；D_in是输入维度；\n# H是隐藏维度；D_out是输出维度。\nlet (N, D_in, H, D_out) = (64, 1000, 100, 10)\n\n# 创建将保存计算图的自动微分上下文\nlet ctx = newContext Tensor[float32]\n\n# 创建随机张量作为输入和输出，并将其包装为Variable。\nlet\n  x = ctx.variable(randomTensor[float32](N, D_in, 1'f32))\n  y = randomTensor[float32](N, D_out, 1'f32)\n\n# ##################################################################\n\n# 定义模型\n\n网络 TwoLayersNet:\n  层:\n    fc1: 线性(D_in, H)\n    fc2: 线性(H, D_out)\n  前向传播 x:\n    x.fc1.relu.fc2\n\n让\n  模型 = 上下文.初始化(TwoLayersNet)\n  优化器 = 模型.优化器(SGD, 学习率 = 1e-4'f32)\n\n# ##################################################################\n# 训练\n\n对于 t 在 0 ..\u003C 500:\n  让\n    y_pred = 模型.前向传播(x)\n    损失 = y_pred.mse_loss(y)\n\n  打印 &\"第 {t} 轮：损失 {loss.value[0]}\"\n\n  损失.反向传播()\n  优化器.更新()\n```\n\n### 预告 使用 Arraymancer 的循环神经网络生成的文本\n\n来自 [示例 6](.\u002Fexamples\u002Fex06_shakespeare_generator.nim)。\n\n在我的笔记本电脑 CPU 上训练了 45 分钟，生成了 4000 个字符\n\n```\n威瑟！\n仆人封印着，只做出些卑鄙的猜测，\n他们不过是那些一直对我不忠的人；\n你的戏码让王后的妻子看到了错误的部分\n带着一个奇怪、可怜又可怕的冷酷的孩子\n罪犯们会如何评价你的角色呢？我，王子！\n现在不是没有牙齿的时候：\n你对此只是肮脏而已。\n我和伙伴们打破了我的复仇，所以，以及他的历史\n就像你们这些领主一样，或者说是港口的真正盐分。\n\n罗密欧：\n你已经发誓要保护自己，并且正在谈论他们；她是不是被你的胆汁谋杀了？\n\n# [...] 查看示例 6 获取完整的文本生成样本\n```\n\n## 目录\n\u003C!-- TOC -->\n\n- [Arraymancer - 一种 n 维张量（ndarray）库。](#arraymancer---a-n-dimensional-tensor-ndarray-library)\n  - [给我看看代码](#show-me-some-code)\n    - [张量的创建和切片](#tensor-creation-and-slicing)\n    - [重塑和拼接](#reshaping-and-concatenation)\n    - [广播](#broadcasting)\n    - [一个简单的两层神经网络](#a-simple-two-layers-neural-network)\n    - [预告 使用 Arraymancer 的循环神经网络生成的文本](#teaser-a-text-generated-with-arraymancers-recurrent-neural-network)\n  - [目录](#table-of-contents)\n  - [安装](#installation)\n  - [完整文档](#full-documentation)\n  - [特性](#features)\n    - [Arraymancer 作为深度学习库](#arraymancer-as-a-deep-learning-library)\n      - [用全连接层（也称为密集层、仿射层或线性层）实现 Fizzbuzz](#fizzbuzz-with-fully-connected-layers-also-called-dense-affine-or-linear-layers)\n      - [用卷积进行手写数字识别](#handwritten-digit-recognition-with-convolutions)\n      - [用堆叠的循环神经网络进行序列分类](#sequence-classification-with-stacked-recurrent-neural-networks)\n    - [CPU、CUDA 和 OpenCL 上的张量](#tensors-on-cpu-on-cuda-and-opencl)\n  - [Arraymancer v0.5.1 - 2019 年 7 月的新功能](#whats-new-in-arraymancer-v051---july-2019)\n  - [选择 Arraymancer 的 4 个理由](#4-reasons-why-arraymancer)\n    - [Python 社区正努力使 NumPy 跟上时代](#the-python-community-is-struggling-to-bring-numpy-up-to-speed)\n    - [研究人员的工作流程是在与低效作斗争](#a-researcher-workflow-is-a-fight-against-inefficiencies)\n    - [几乎无需依赖即可分发](#can-be-distributed-almost-dependency-free)\n    - [弥合深度学习研究与生产之间的鸿沟](#bridging-the-gap-between-deep-learning-research-and-production)\n    - [那么为什么选择 Arraymancer？](#so-why-arraymancer-)\n  - [未来的抱负](#future-ambitions)\n\n\u003C!-- \u002FTOC -->\n\n## 安装\n\nNim 在一些 Linux 发行版的软件仓库中以及 macOS 的 Homebrew 中都可以找到。\n\n不过，我建议通过 [``choosenim``](https:\u002F\u002Fgithub.com\u002Fdom96\u002Fchoosenim) 将 Nim 安装到您的用户目录中。一旦使用 choosenim 安装了 Nim，您就可以运行 `nimble install arraymancer`，这将下载最新的 Arraymancer 版本及其所有依赖项。\n\n如果您想安装 Arraymancer 的开发版本，可以使用 `nimble install arraymancer@#head`。\n\nArraymancer 需要 BLAS 和 LAPACK 库。\n\n- 在 Windows 上，您可以从 OpenBLAS 网站的二进制包部分获取 [OpenBLAS](https:\u002F\u002Fwww.openblas.net) 库，它将 BLAS 和 LAPACK 合并为一个 DLL 文件（`libopenblas.dll`）。或者，您也可以从 [LAPACK for Windows](https:\u002F\u002Ficl.cs.utk.edu\u002Flapack-for-windows\u002Flapack\u002F) 网站单独下载 BLAS 和 LAPACK 库。然后，您需要将这些 DLL 文件复制或解压到您的系统路径中的某个文件夹，或者放到包含编译目标的文件夹中。\n- 在 macOS 上，Apple Accelerate Framework 已经包含在所有 macOS 版本中，提供了这些库。\n- 在 Linux 上，您可以使用包管理器下载 libopenblas 和 liblapack。\n\nWindows 用户可能需要从 [openblas](https:\u002F\u002Fwww.openblas.net) 的二进制发布部分下载 `libopenblas.dll`，将其解压到编译\n\n## 完整文档\n\n详细的 API 文档可在 Arraymancer 官方 [文档](https:\u002F\u002Fmratsim.github.io\u002FArraymancer\u002F) 中找到。注意：此文档仅针对 0.X 版本生成。请查看 [示例文件夹](examples\u002F) 以了解最新的开发进展。\n\n## 特性\n\n目前，Arraymancer 主要处于多维数组阶段，具体来说，Arraymancer 提供以下功能：\n\n- 基本数学运算推广到张量（sin、cos 等）\n- 矩阵代数原语：矩阵-矩阵、矩阵-向量乘法\n- 简单高效的切片操作，包括使用范围和步长\n- 无需担心“矢量化”操作\n- 支持广播。与 NumPy 不同，它是显式的，您只需使用 `+.` 而不是 `+`\n- 丰富的重塑操作：拼接、重塑、拆分、分块、排列、转置\n- 支持最多 6 维的张量。例如，4 部 3D RGB 微电影，每部 10 秒，就是 6 维：\n  `[4, 10, 3, 64, 1920, 1080]` 对应 `[影片数量、时间、颜色、深度、高度、宽度]`\n- 可以读取和写入 .csv、Numpy (.npy) 和 HDF5 文件\n- OpenCL 和 CUDA 加速的张量（目前功能不如 CPU 张量丰富）\n- 协方差矩阵\n- 特征值和特征向量分解\n- 最小二乘法求解器\n- K-means 和 PCA（主成分分析）\n\n### Arraymancer 作为深度学习库\n\n深度学习功能目前仍可探索，但被认为不稳定，因为我还在完善其最终接口。\n\n提醒：最终接口仍在 **开发中**。\n\n您还可以观看以下动画版 [神经网络演示](https:\u002F\u002Fgithub.com\u002FVindaar\u002FNeuralNetworkLiveDemo)，该演示展示了通过 [nim-plotly](https:\u002F\u002Fgithub.com\u002Fbrentp\u002Fnim-plotly) 进行的实时训练。\n\n#### Fizzbuzz 用全连接层（也称为密集层、仿射层或线性层）\n\n神经网络定义摘自 [示例 4](examples\u002Fex04_fizzbuzz_interview_cheatsheet.nim)。\n\n```Nim\n导入 arraymancer\n\n常量\n  数字位数 = 10\n  隐藏层节点数 = 100\n\n网络 FizzBuzzNet:\n  层:\n    隐藏层: 线性(数字位数, 隐藏层节点数)\n    输出层: 线性(隐藏层节点数, 4)\n  前向传播 x:\n    x.隐藏层.relu.输出层\n\n让\n  上下文 = 新建上下文 Tensor[float32]\n  模型 = 上下文.初始化(FizzBuzzNet)\n  优化器 = 模型.优化器(SGD, 0.05'f32)\n# ....\n打印答案\n# @[\"1\", \"2\", \"fizz\", \"4\", \"buzz\", \"6\", \"7\", \"8\", \"fizz\", \"10\",\n\n#   \"11\", \"12\", \"13\", \"14\", \"15\", \"16\", \"17\", \"fizz\", \"19\", \"buzz\",\n#   \"fizz\", \"22\", \"23\", \"24\", \"buzz\", \"26\", \"fizz\", \"28\", \"29\", \"30\",\n#   \"31\", \"32\", \"fizz\", \"34\", \"buzz\", \"36\", \"37\", \"38\", \"39\", \"40\",\n#   \"41\", \"fizz\", \"43\", \"44\", \"fizzbuzz\", \"46\", \"47\", \"fizz\", \"49\", \"50\",\n#   \"fizz\", \"52\",\"53\", \"54\", \"buzz\", \"56\", \"fizz\", \"58\", \"59\", \"fizzbuzz\",\n#   \"61\", \"62\", \"63\", \"64\", \"buzz\", \"fizz\", \"67\", \"68\", \"fizz\", \"buzz\",\n#   \"71\", \"fizz\", \"73\", \"74\", \"75\", \"76\", \"77\",\"fizz\", \"79\", \"buzz\",\n#   \"fizz\", \"82\", \"83\", \"fizz\", \"buzz\", \"86\", \"fizz\", \"88\", \"89\", \"90\",\n#   \"91\", \"92\", \"fizz\", \"94\", \"buzz\", \"fizz\", \"97\", \"98\", \"fizz\", \"buzz\"]\n```\n\n#### 使用卷积的手写数字识别\n\n神经网络定义摘自[示例 2](examples\u002Fex02_handwritten_digits_recognition.nim)。\n\n```Nim\nimport arraymancer\n\nnetwork DemoNet:\n  layers:\n    cv1:        Conv2D(@[1, 28, 28], out_channels = 20, kernel_size = (5, 5))\n    mp1:        Maxpool2D(cv1.out_shape, kernel_size = (2,2), padding = (0,0), stride = (2,2))\n    cv2:        Conv2D(mp1.out_shape, out_channels = 50, kernel_size = (5, 5))\n    mp2:        MaxPool2D(cv2.out_shape, kernel_size = (2,2), padding = (0,0), stride = (2,2))\n    fl:         Flatten(mp2.out_shape)\n    hidden:     Linear(fl.out_shape[0], 500)\n    classifier: Linear(500, 10)\n  forward x:\n    x.cv1.relu.mp1.cv2.relu.mp2.fl.hidden.relu.classifier\n\nlet\n  ctx = newContext Tensor[float32] # 自动求导\u002F神经网络图\n  model = ctx.init(DemoNet)\n  optim = model.optimizer(SGD, learning_rate = 0.01'f32)\n\n# ...\n# 在笔记本电脑的 CPU 上，几分钟内准确率就能超过 90%\n```\n\n#### 使用堆叠循环神经网络进行序列分类\n\n神经网络定义摘自[示例 5](examples\u002Fex05_sequence_classification_GRU.nim)。\n\n```Nim\nimport arraymancer\n\nconst\n  HiddenSize = 256\n  Layers = 4\n  BatchSize = 512\n\n\nnetwork TheGreatSequencer:\n  layers:\n    gru1: GRULayer(1, HiddenSize, 4) # (输入特征数, 隐藏层大小, 堆叠层数)\n    fc1: Linear(HiddenSize, 32)                  # 每个 GRU 层一个分类器\n    fc2: Linear(HiddenSize, 32)\n    fc3: Linear(HiddenSize, 32)\n    fc4: Linear(HiddenSize, 32)\n    classifier: Linear(32 * 4, 3)                # 将四个分类器的输出堆叠后送入一个学习型分类器\n  forward x, hidden0:\n    let\n      (output, hiddenN) = gru1(x, hidden0)\n      clf1 = hiddenN[0, _, _].squeeze(0).fc1.relu\n      clf2 = hiddenN[1, _, _].squeeze(0).fc2.relu\n      clf3 = hiddenN[2, _, _].squeeze(0).fc3.relu\n      clf4 = hiddenN[3, _, _].squeeze(0).fc4.relu\n\n    # 将所有结果拼接起来\n    # 由于目前尚未实现拼接操作的反向传播，我们通过堆叠的方式“作弊”\n    # 然后再展平\n    result = stack(clf1, clf2, clf3, clf4, axis = 2)\n    result = classifier(result.flatten)\n\n# 初始化模型\nlet\n  ctx = newContext Tensor[float32]\n  model = ctx.init(TheGreatSequencer)\n  optim = model.optimizer(SGD, 0.01'f32)\n\n# ...\nlet exam = ctx.variable([\n    [float32 0.10, 0.20, 0.30], # 递增\n    [float32 0.10, 0.90, 0.95], # 递增\n    [float32 0.45, 0.50, 0.55], # 递增\n    [float32 0.10, 0.30, 0.20], # 非单调\n    [float32 0.20, 0.10, 0.30], # 非单调\n    [float32 0.98, 0.97, 0.96], # 递减\n    [float32 0.12, 0.05, 0.01], # 递减\n    [float32 0.95, 0.05, 0.07]  # 非单调\n  ])\n# ...\necho answer.unsqueeze(1)\n# Tensor[ex05_sequence_classification_GRU.SeqKind] of shape [8, 1] of type \"SeqKind\" on backend \"Cpu\"\n# \t  Increasing|\n# \t  Increasing|\n# \t  Increasing|\n# \t  NonMonotonic|\n# \t  NonMonotonic|\n# \t  Increasing| \u003C----- 错误！\n# \t  Decreasing|\n# \t  NonMonotonic|\n```\n\n#### 组合模型\n\n网络模型也可以作为其他网络定义中的层。\n上面的手写数字识别模型也可以这样写：\n\n```Nim\nimport arraymancer\n\nnetwork SomeConvNet:\n  layers h, w:\n    cv1:        Conv2D(@[1, h, w], 20, (5, 5))\n    mp1:        Maxpool2D(cv1.out_shape, (2,2), (0,0), (2,2))\n    cv2:        Conv2D(mp1.out_shape, 50, (5, 5))\n    mp2:        MaxPool2D(cv2.out_shape, (2,2), (0,0), (2,2))\n    fl:         Flatten(mp2.out_shape)\n  forward x:\n    x.cv1.relu.mp1.cv2.relu.mp2.fl\n\n# 这个模型可以这样初始化：let model = ctx.init(SomeConvNet, h = 28, w = 28)\n\n# 函数 `out_shape` 和 `in_shape` 返回一个 `seq[int]` 是一种约定（但并非严格必要），\n# 适用于具有明确输出和输入尺寸的层或模型。\nproc out_shape*[T](self: SomeConvNet[T]): seq[int] =\n  self.fl.out_shape\nproc in_shape*[T](self: SomeConvNet[T]): seq[int] =\n  self.cv1.in_shape\n\nnetwork DemoNet:\n  layers:\n    # 这里我们将之前定义的 SomeConvNet 用作一层\n    cv:         SomeConvNet(28, 28)\n    hidden:     Linear(cv.out_shape[0], 500)\n    classifier: Linear(hidden.out_shape[0], 10)\n  forward x:\n    x.cv.hidden.relu.classifier\n```\n\n#### 自定义层\n\n也可以创建完全自定义的层。\n相关文档可以在[官方 API 文档](https:\u002F\u002Fmratsim.github.io\u002FArraymancer\u002Fnn_dsl.html)中找到。\n\n### CPU、CUDA 和 OpenCL 上的张量\n\n目前，Tensor、CudaTensor 和 CLTensor 尚未实现完全相同的功能。此外，CudaTensor 和 CLTensor 只能是 float32 或 float64 类型，而 CpuTensor 则可以是整数、字符串、布尔值或任何自定义对象。\n\n以下是核心功能的对比表。\n\n| 操作                                            | Tensor                      | CudaTensor                 | ClTensor                   |\n| ------------------------------------------------- | --------------------------- | -------------------------- | -------------------------- |\n| 访问张量属性                                       | [x]                         | [x]                        | [x]                        |\n| 张量创建                                           | [x]                         | 通过转换 CPU 张量        | 通过转换 CPU 张量        |\n| 访问或修改单个元素                                 | [x]                         | []                         | []                         |\n| 遍历张量                                           | [x]                         | []                         | []                         |\n| 张量切片                                           | [x]                         | [x]                        | [x]                        |\n| 切片赋值 `a[1,_] = 10`                             | [x]                         | []                         | []                         |\n| 比较 `==`                                          | [x]                         | []                         | []                         |\n| 元素级基本运算                                     | [x]                         | [x]                        | [x]                        |\n| 通用函数                                           | [x]                         | []                         | []                         |\n| 自动广播操作                                       | [x]                         | [x]                        | [x]                        |\n| 矩阵-矩阵和矩阵-向量乘法                           | [x]                         | [x]                        | [x]                        |\n| 显示张量                                           | [x]                         | [x]                        | [x]                        |\n| 高阶函数（map、apply、reduce、fold）                | [x]                         | 仅限内部使用              | 仅限内部使用              |\n| 转置                                               | [x]                         | [x]                        | []                         |\n| 转换为连续存储                                     | [x]                         | [x]                        | []                         |\n| 改变形状                                           | [x]                         | [x]                        | []                         |\n| 显式广播                                           | [x]                         | [x]                        | [x]                        |\n| 维度置换                                           | [x]                         | []                         | []                         |\n| 沿现有维度拼接张量                                 | [x]                         | []                         | []                         |\n| 压缩单例维度                                       | [x]                         | [x]                        | []                         |\n| 切片 + 压缩                                        | [x]                         | []                         | []                         |\n\n## Arraymancer 的新特性\n\n完整的变更日志可在 [changelog.md](.\u002Fchangelog.md) 中查看。\n\n## 为什么选择 Arraymancer 的四个理由\n\n### Python 社区难以使 NumPy 跟上时代步伐\n\n- Numba JIT 编译器\n- Dask 延迟并行计算图\n- Cython 用于简化 Python 中的数值计算\n- 由于 GIL 的存在，纯 Python 中无法实现共享内存并行化（OpenMP）\n- 使用“向量化操作”（即避免在 Python 中使用 for 循环）\n\n为什么不使用一种语言，将所有必要的组件整合在一起，构建出兼具 Python 易用性与高效性的科学计算库呢？\n\nOpenMP 直接内置其中。\n\n### 研究人员的工作流程往往与低效作斗争\n\n在需要大量科学计算的研究领域中，研究人员通常会经历以下工作流程：Mathematica\u002FMatlab\u002FPython\u002FR（原型开发）→ C\u002FC++\u002FFortran（速度与内存优化）。\n\n为什么不使用一种既像 Python 一样高效，又像 C 语言一样快速的语言呢？只需编写一次代码，便无需花费数月时间在更低层次上重复同样的工作。\n\n### 几乎无需依赖即可分发\n\nArraymancer 的模型可以被打包成一个自包含的二进制文件，该文件仅依赖于 BLAS 库，如 OpenBLAS、MKL 或 Apple Accelerate（所有 Mac 和 iOS 设备上均已提供）。\n\n这意味着用户无需安装庞大的库或语言生态系统即可使用 Arraymancer。这也使其天然适用于资源受限的设备，例如手机和 Raspberry Pi。\n\n### 弥合深度学习研究与生产之间的鸿沟\n\n当前的深度学习框架主要分为两类：\n\n- 研究类：Theano、TensorFlow、Keras、Torch、PyTorch\n- 生产类：Caffe、Darknet、（TensorFlow）\n\n此外，除非使用 OpenCV，否则 Python 的预处理步骤通常需要自定义实现（例如手机上的文本\u002F语音预处理）。\n\n- 以可靠的方式管理和部署 Python（2.7、3.5、3.6）及其软件包版本，需要具备 DevOps 技能（virtualenv、Docker等）。\n- Python 数据科学生态系统无法在嵌入式设备（如 Nvidia Tegra 或无人机）以及手机上运行，尤其是预处理相关的依赖项。\n- TensorFlow 本应弥合研究与生产之间的差距，但其语法和易用性令人头疼。对于研究人员而言，仍然需要两次编码：“先用 Keras 做原型，等到需要底层操作时再转到 TensorFlow”。\n- 已部署的模型是静态的，没有任何框架提供添加新观测值或训练样本的接口。如果希望将模型作为具有在线学习能力的 Web 服务使用，该怎么办？\n\n[相关 XKCD 漫画，2018 年 4 月 30 日](https:\u002F\u002Fxkcd.com\u002F1987\u002F)\n\n![Python 环境混乱](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fmratsim_Arraymancer_readme_79d99e8fcde8.png)\n\n### 那么，为什么选择 Arraymancer？\n\n上述种种痛点看似艰巨，然而得益于 Nim 语言，我们得以实现 Arraymancer：\n\n- 速度媲美 C 语言\n- 通过 Intel MKL\u002FOpenBLAS 甚至 NNPACK 加速计算\n- 支持 CUDA 和 CuDNN，并可通过元编程动态生成自定义 CUDA 内核\n- 几乎无需依赖即可分发（仅需 BLAS 库）\n- 类似 Python 的语法，支持自定义运算符 `a * b` 进行张量乘法，而非 `a.dot(b)`（NumPy\u002FTensorFlow）或 `a.mm(b)`（Torch）\n- 类似 NumPy 的切片操作，如 `t[0..4, 2..10|2]`\n- 对于 Nim 尚未提供的功能，可以通过 Nim 与 C、C++、Objective-C 或 JavaScript 的绑定将其引入 Nim。Nim 还提供了非官方的 Python↔Nim 绑定。\n\n## 未来的抱负\n\n既然 apparently 要想成功就得有个愿景，那我就希望 Arraymancer 能成为：\n\n- 深度学习视频处理的首选工具。比如：`vid = load_video(\".\u002Fcats\u002Fyoutube_cat_video.mkv\")`\n- 支持 JavaScript、WebAssembly、Apple Metal、ARM 设备、AMD ROCm、OpenCL 等多种平台，你想得到的它都能支持。\n- 成为一款《星际争霸 II》AI 机器人的基础框架。\n- 专门面向加密货币挖矿用的 FPGA，因为它们把 GPU 的价格抬得太高了，让真正搞深度学习的研究者都买不起了。","# Arraymancer 快速上手指南\n\nArraymancer 是一个基于 Nim 语言的高性能 N 维张量（ndarray）库，灵感来源于 Numpy 和 PyTorch。它支持 CPU、CUDA 和 OpenCL 后端，适用于科学计算、机器学习及深度学习任务。\n\n## 环境准备\n\n### 系统要求\n- **操作系统**：Windows, macOS, Linux\n- **编译器**：Nim (推荐最新稳定版)\n- **硬件加速（可选）**：\n  - NVIDIA GPU (需安装 CUDA Toolkit)\n  - 支持 AVX512 指令集的 CPU (如需极致性能)\n\n### 前置依赖\nArraymancer 依赖线性代数库 **BLAS** 和 **LAPACK**。请根据操作系统预先安装：\n\n- **Windows**:\n  - 下载 [OpenBLAS](https:\u002F\u002Fwww.openblas.net\u002F) 二进制包。\n  - 获取 `libopenblas.dll`，将其复制到系统 PATH 路径下或项目编译输出目录中。\n- **macOS**:\n  - 系统自带 Apple Accelerate Framework，无需额外安装。\n- **Linux**:\n  - 使用包管理器安装，例如 Ubuntu\u002FDebian: `sudo apt-get install libopenblas-dev liblapack-dev`。\n\n> **提示**：国内用户安装 Nim 推荐使用 `choosenim` 工具，它支持自动选择国内镜像源加速下载。\n\n## 安装步骤\n\n### 1. 安装 Nim\n推荐使用 `choosenim` 进行安装和管理（支持 Windows\u002FmacOS\u002FLinux）：\n\n```bash\n# 下载安装 choosenim (Windows PowerShell)\ncurl https:\u002F\u002Fnim-lang.org\u002Fchoosenim\u002Finit_stable.sh -o init_stable.sh\nsh init_stable.sh\n\n# 或者直接在终端运行安装脚本\ncurl https:\u002F\u002Fnim-lang.org\u002Fchoosenim\u002Finit_stable.sh | sh\n```\n\n安装完成后，确保 `nim` 和 `nimble` 命令可用。\n\n### 2. 安装 Arraymancer\n使用 Nim 的包管理器 `nimble` 安装：\n\n```bash\n# 安装最新稳定版\nnimble install arraymancer\n\n# 或者安装开发最新版\nnimble install arraymancer@#head\n```\n\n## 基本使用\n\n以下示例展示如何创建张量、进行切片操作以及执行简单的广播运算。\n\n### 1. 创建与切片 (Tensor Creation and Slicing)\n\n创建一个范德蒙德矩阵并进行切片：\n\n```Nim\nimport math, arraymancer\n\nconst\n    x = @[1, 2, 3, 4, 5]\n    y = @[1, 2, 3, 4, 5]\n\nvar\n    vandermonde = newSeq[seq[int]]()\n    row: seq[int]\n\nfor i, xx in x:\n    row = newSeq[int]()\n    vandermonde.add(row)\n    for j, yy in y:\n        vandermonde[i].add(xx^yy)\n\nlet foo = vandermonde.toTensor()\n\necho foo\n# 输出形状为 [5, 5] 的张量\n\necho foo[1..2, 3..4] # 切片操作\n# 输出形状为 [2, 2] 的子张量\n\necho foo[_|-1, _] # 反转行顺序\n```\n\n### 2. 广播机制 (Broadcasting)\n\n演示类似 Numpy 的广播加法：\n\n```Nim\nimport arraymancer\n\nlet j = [0, 10, 20, 30].toTensor.reshape(4,1)\nlet k = [0, 1, 2].toTensor.reshape(1,3)\n\necho j +. k\n# 输出形状为 [4, 3] 的张量，实现行列自动广播相加\n# |0      1     2|\n# |10    11    12|\n# |20    21    22|\n# |30    31    32|\n```\n\n### 3. 编译与运行\n\n将代码保存为 `main.nim`，使用以下命令编译并运行（开启释放模式以获得最佳性能）：\n\n```bash\n# 基础编译\nnim c -r main.nim\n\n# 开启优化发布模式 (推荐)\nnim c -d:release -r main.nim\n\n# 若需启用 CUDA 支持\nnim c -d:cuda -d:release -r main.nim\n```\n\n> **注意**：默认情况下 Arraymancer 会自动查找系统中的 BLAS\u002FLAPACK 库。如果找不到，可通过 `-d:blas=openblas` 等标志指定，或确保动态链接库在正确路径下。","某嵌入式视觉团队需要在资源受限的工业相机上部署实时缺陷检测模型，同时保持算法迭代的高效性。\n\n### 没有 Arraymancer 时\n- **开发效率低下**：团队被迫在 Python 中验证算法后，用 C++ 重写底层张量运算以适配嵌入式环境，双重维护导致原型验证周期长达数周。\n- **硬件适配困难**：缺乏统一的后端抽象，针对 CPU、GPU 或特定嵌入式加速器（如 OpenCL 设备）需分别编写异构代码，移植成本极高。\n- **性能与体积失衡**：引入重型深度学习框架会导致内存占用超标，而手动优化 BLAS\u002FLAPACK 调用又极易出错，难以在有限算力下达成实时推理。\n- **编译等待漫长**：C++ 项目每次修改底层矩阵逻辑都需要漫长的重新编译时间，严重阻碍了参数调优和实验频率。\n\n### 使用 Arraymancer 后\n- **单一语言全流程**：利用 Nim 语言特性，团队直接用 Arraymancer 完成从数据预处理、PCA 降维到模型训练的全流程，无需跨语言重写，原型落地缩短至数天。\n- **后端无缝切换**：通过简单的编译标志（如 `-d:cuda` 或 `-d:opencl`），同一份张量代码即可在服务器 GPU 上训练，并平滑部署到嵌入式设备的 OpenCL 加速器上。\n- **极致性能控制**：Arraymancer 提供类似 NumPy 的 ergonomics，却生成原生机器码；结合 `-d:danger` 移除边界检查及自定义 BLAS 库，在极小内存占用下实现毫秒级推理。\n- **秒级编译迭代**：得益于 Nim 的极速编译能力，即使修改底层张量操作，整个项目也能在 5 秒内完成构建，让工程师能高频次尝试新的算法策略。\n\nArraymancer 让开发者在享受脚本语言般开发体验的同时，获得了足以驾驭嵌入式边缘计算的原生性能与跨平台灵活性。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fmratsim_Arraymancer_b2e06d92.png","mratsim","Mamy Ratsimbazafy","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002Fmratsim_cc2c0683.jpg","Ethereum Blockchain R&D ✦ ZK Cryptography Engineering ✦ Data Scientist ✦ High Performance, Parallel, Scientific and GPU computing",null,"Paris","mamy_github@numforge.co","https:\u002F\u002Fgithub.com\u002Fmratsim",[81,85,89,93],{"name":82,"color":83,"percentage":84},"Nim","#ffc200",98.1,{"name":86,"color":87,"percentage":88},"Python","#3572A5",1.8,{"name":90,"color":91,"percentage":92},"Julia","#a270ba",0,{"name":94,"color":95,"percentage":92},"Ruby","#701516",1397,100,"2026-03-26T18:14:47","Apache-2.0",4,"Linux, macOS, Windows","非必需。支持 NVIDIA GPU (需 CUDA 后端) 或 OpenCL 设备。若启用 CUDA 需安装 CUDA Toolkit 和可选的 CuDNN；具体版本未说明，由用户编译时通过 `-d:cuda` 标志决定。","未说明",{"notes":105,"python":106,"dependencies":107},"1. 该工具基于 Nim 语言，不使用 Python。2. 必须安装 BLAS 和 LAPACK 线性代数库（Windows 需手动下载 dll，macOS 自带 Accelerate 框架，Linux 可通过包管理器安装）。3. 推荐使用 choosenim 安装 Nim，并通过 nimble 安装本库。4. 支持通过编译标志 (-d:openmp, -d:cuda, -d:avx512 等) 定制后端和优化指令集。5. 项目状态标记为“实验性”(experimental)。","不需要 (基于 Nim 语言)",[108,109,110],"Nim 编译器","BLAS 库 (如 OpenBLAS, MKL, Apple Accelerate)","LAPACK 库",[112,14],"视频",[114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133],"tensor","nim","multidimensional-arrays","cuda","deep-learning","machine-learning","cudnn","high-performance-computing","gpu-computing","matrix-library","neural-networks","parallel-computing","openmp","linear-algebra","ndarray","opencl","gpgpu","iot","automatic-differentiation","autograd","2026-03-27T02:49:30.150509","2026-04-07T09:47:59.779361",[137,142,147,152],{"id":138,"question_zh":139,"answer_zh":140,"source_url":141},21590,"在使用 OpenMP 和调试宏（如 --lineDir:on）编译时遇到 '#pragma omp atomic' 错误怎么办？","这是一个已知问题，当启用行号调试信息并与 OpenMP 原子操作结合使用时，生成的 C 代码会导致语法错误。维护者已确认该问题并进行了修复。如果暂时无法升级，可以通过使用 release 模式编译来绕过此错误。维护者也表示计划尽快弃用 OpenMP 以避免此类问题。","https:\u002F\u002Fgithub.com\u002Fmratsim\u002FArraymancer\u002Fissues\u002F407",{"id":143,"question_zh":144,"answer_zh":145,"source_url":146},21591,"Arraymancer 的性能与 Python (NumPy) 相比如何？为什么我的基准测试显示它更慢？","在单线程模式下，Arraymancer 的性能通常与多线程 NumPy（通过 OpenMP 和 Intel MKL）相当，甚至更快（在某些基准测试中快 2.7 倍）。如果您发现性能显著下降（例如慢 3 倍），这通常是由 Nim 编译器本身的回归引起的（特定提交导致），而非 Arraymancer 库的问题。建议检查 Nim 版本，升级到修复了该回归的版本，或者使用优化后的代码（避免临时分配）以获得最佳性能（可提升至 3.7 秒完成特定任务）。","https:\u002F\u002Fgithub.com\u002Fmratsim\u002FArraymancer\u002Fissues\u002F190",{"id":148,"question_zh":149,"answer_zh":150,"source_url":151},21592,"如何在 Arraymancer 中实现类似 NumPy 的 einsum（爱因斯坦求和约定）功能？","社区已经实现了 einsum 的概念验证。您可以使用宏和模板定义类似 `einsum(c, d): c[i,j,k,l] * d[k,l]` 的语法。实现思路是围绕张量轴创建硬编码循环。虽然目前主要支持行主序张量，但可以作为基础扩展以支持更多张量或优化循环。建议参考相关物理学家对爱因斯坦求和的理解来实现，并利用现有的测试用例（如矩阵 - 向量乘法、点积等）进行验证。","https:\u002F\u002Fgithub.com\u002Fmratsim\u002FArraymancer\u002Fissues\u002F124",{"id":153,"question_zh":154,"answer_zh":155,"source_url":156},21593,"在 Nim devel 分支上编译 Arraymancer 时遇到 AVX-512 内联失败错误（target specific option mismatch）如何解决？","此错误通常由 Nim 编译器的特定更改（回归）引起，导致生成的 C 代码在调用 AVX-512 内在函数（如 `_mm512_setzero_si512`）时出现目标选项不匹配。该问题已被定位到具体的 Nim PR（#17311）。解决方法包括：等待 Nim 上游修复该回归，或者暂时回退到稳定的 Nim 版本（如 1.4.8，在该版本上通常可以正常编译），直到问题在 devel 分支得到解决。","https:\u002F\u002Fgithub.com\u002Fmratsim\u002FArraymancer\u002Fissues\u002F505",[158,163,168,173,178,183,188,193,198,203],{"id":159,"version":160,"summary_zh":161,"released_at":162},127597,"v0.7.0","Arraymancer v0.7.0 2021年7月4日 “冰之记忆”\n=====================================================\n\n> 本版本以史蒂文·埃里克森史诗级黑暗奇幻巨著《玛拉赞：陨落之书》的第三部《冰之记忆》（2001年）命名。\n\n变更：\n  - 添加 `toUnsafeView` 作为 `dataArray` 的替代，用于返回 `ptr UncheckedArray`\n  - 修复文档生成问题\n  - 新增 `cumsum`、`cumprod`\n  - 修复最小二乘法求解器\n  - 修复均方误差的反向传播\n  - 适配上游符号解析的变化\n  - 实现基础的图卷积网络\n  - 重写切片教程\n  - 支持n维张量的美观打印\n  - 修正编译问题，以兼容从 Nim 1.0 到开发版的各个版本\n\n感谢 @Vindaar 在我暂时退居幕后期间，持续维护仓库、更新文档、改进美观打印功能，并在 Discord 上解答了无数问题。\n感谢 @filipeclduarte 提供的 cumsum\u002Fcumprod 实现，@Clonkk 更新原始数据访问的方式，@struggle 发现并报告了均方误差反向传播中的一个 bug，\n@timotheecour 将上游的新依赖项传递到下游，以及 @anon767 贡献的图神经网络实现。","2021-07-04T09:49:55",{"id":164,"version":165,"summary_zh":166,"released_at":167},127598,"v0.6.1","v0.6.0 的 nimble 文件中仅包含 v0.5.2。","2020-11-03T07:35:39",{"id":169,"version":170,"summary_zh":171,"released_at":172},127599,"v0.6.0","Arraymancer v0.6.0 - 风行者\r\n=====================================================\r\n\r\n> 本版本以阿兰·达马西奥的《风行者》（2004年，法语原名“La Horde du Contrevent”）命名。\r\n\r\n更改内容:\r\n  - 用于计算对称矩阵特征向量的 `symeig` 过程现在接受一个 `uplo` 字符参数。这允许只填充矩阵的上三角或下三角部分，另一部分在计算中不会被使用。\r\n  - 添加了 `svd_randomized`，这是一种通过随机采样实现的快速且精确的奇异值分解近似方法。对于大规模数据集的奇异值分解来说，这种方法是标准的高效解决方案，因为直接对大型矩阵进行奇异值分解非常耗时。\r\n  - `pca` 现在使用随机化奇异值分解代替计算协方差矩阵，从而能够高效处理大规模问题。它现在接受 `center`、`n_oversamples` 和 `n_power_iters` 参数。需要注意的是，不进行中心化的主成分分析等价于截断的奇异值分解。\r\n  - 增加了 LU 分解功能\r\n  - 增加了 QR 分解功能\r\n  - 引入了 `hilbert` 函数，用于生成著名的病态希尔伯特矩阵。该矩阵非常适合用来测试分解算法的稳定性。\r\n  - 引入了 `arange` 过程，用于在指定范围内按给定步长生成等间距的数值序列。\r\n  - 错误函数的参数顺序已调整为 `(y_pred, y_target)`（之前是 `(y_target, y_pred)`），从而支持 `y_pred.accuracy_score(y)` 的语法。Arraymancer 中现有的所有错误函数在参数顺序上都是可交换的，因此现有代码仍能正常运行。\r\n  - 添加了一个 `solve` 过程，用于求解用矩阵表示的线性方程组。\r\n  - 在自动微分和神经网络模块中添加了 `softmax` 层，作为对 SoftmaxCrossEntropy 层的补充，后者将 softmax 操作与负对数似然损失结合在一起。\r\n  - 随机梯度下降算法现在新增了带有动量的版本。\r\n\r\n缺陷修复:\r\n  - 当结果矩阵为列主序时，`gemm` 可能会崩溃。\r\n  - 矩阵乘法与矩阵加法的自动融合操作 `(A * X) + b` 可能会意外更新矩阵 `b`。\r\n  - 复数转换器不再污染全局命名空间，并且不会因调用歧义而阻止数字类型通过 `$` 进行字符串转换。\r\n  - 已修复就地除法中的一个错误：原代码中存在拼写错误，导致实际执行的是减法操作。\r\n  - 解决了 NVIDIA 的 “nanosecond” 与 Nim 时间模块中的 “nanosecond” 名称冲突问题，该冲突曾导致 CUDA 编译失败。\r\n\r\n破坏性变更:\r\n  - 在 `symeig` 中，`eigenvectors` 参数现更名为 `return_eigenvectors`。\r\n  - 对于带切片的 `symeig`，新的 `uplo` 参数现在位于切片参数之前。\r\n  - PCA 输入参数 `nb_components` 已更名为 `n_components`。\r\n  - PCA 输出元组原本使用 `(results, components)` 的命名方式，现已改为 `(projected, components)`。\r\n  - 移除了一个可以将数据矩阵投影到已有主成分轴上的 `pca` 重载函数。用户可以直接将均值中心化的数据矩阵与主成分矩阵相乘来实现相同的功能。\r\n  - 复数","2020-01-08T23:45:47",{"id":174,"version":175,"summary_zh":176,"released_at":177},127600,"v0.5.2","修复“.nimble”中的打包错误，并更新了README和变更日志。","2019-07-19T16:03:38",{"id":179,"version":180,"summary_zh":181,"released_at":182},127601,"v0.5.1","影响向后兼容性的变更：\n  - 无\n\n新增功能：\n  - 0.20.x 兼容性（提交：0921190）\n  - 复数支持\n  - `Einsum`\n  - 用于自然语言处理的简单空白符分词器\n  - Laser 后端预览版，用于矩阵乘法，无需 SIMD 自动检测（在整数矩阵乘法上已提速 5 倍）\n\n修复：\n  - 修复以张量形式读取图像时高\u002F宽顺序错误的问题\n\n感谢 @chimez 提供的复数支持及对 0.20 版本的更新，感谢 @metasyn 提供的分词器，感谢 @xcokazaki 对图像维度问题的修复，以及感谢 @Vindaar 实现的 einsum 功能。","2019-07-19T00:01:15",{"id":184,"version":185,"summary_zh":186,"released_at":187},127602,"v0.5.0","> 本次发布以罗杰·泽拉兹尼的杰作《安珀编年史》第三部《独角兽的印记》（1975年）命名。\n\n影响向后兼容性的变更：\n  - PCA 被拆分为两个：\n    - 旧版 PCA，输入为 `pca(x: Tensor, nb_components: int)`，现在会返回一个元组，包含结果张量和按降序排列的主成分张量，而不再仅返回结果。\n    - 新版 PCA `pca(x: Tensor, principal_axes: Tensor)` 将把输入 x 投影到提供的主轴上。\n\n变更内容：\n  - 数据集：\n    - MNIST 现在会自动下载并缓存。\n    - 新增 IMDB 电影评论数据集。\n  - 输入输出：\n    - 支持 NumPy 文件格式。\n    - 支持图像的读取和写入（jpg、bmp、png、tga）。\n    - 支持 HDF5 的读写操作。\n  - 机器学习：\n    - K-means 聚类。\n  - 神经网络与自动微分：\n    - 神经网络中支持减法、求和及堆叠操作。\n    - 循环神经网络：新增 GRUCell、GRU 以及融合堆叠 GRU 的支持。\n    - 神经网络声明式语言现支持 GRU。\n    - 新增嵌入层，支持最多三维的输入张量，形状可为 [batch_size, sequence_length, features] 或 [sequence_length, batch_size, features]。索引可以使用任意大小的整数、字节、字符或枚举类型。\n    - 稀疏 softmax 交叉熵损失现支持目标张量的索引类型为任意大小的整数、字节、字符或枚举。\n    - 新增 ADAM 优化器（自适应矩估计）。\n    - 新增哈达玛积的反向传播（逐元素矩阵乘法）。\n    - 新增 Xavier Glorot、Kaiming He 和 Yann LeCun 权重初始化方法。\n    - 神经网络声明式语言会自动按照以下方案初始化权重：\n      - 线性层和卷积层：Kaiming 初始化（适用于 ReLU 激活函数）。\n      - GRU：Xavier 初始化（适用于内部的 tanh 和 sigmoid 激活函数）。\n      - 嵌入层：目前声明式语言暂不支持初始化。\n  - 张量：\n    - 新增张量分割与分块功能。\n    - 通过 `index_select` 实现高级索引。\n    - 支持除法广播、标量除法以及乘法广播。\n    - 高维张量的 `toSeq` 导出功能。\n  - 端到端示例：\n    - [基于 RNN 的序列\u002F小型时间序列分类示例](https:\u002F\u002Fgithub.com\u002Fmratsim\u002FArraymancer\u002Fblob\u002Fv0.5.0\u002Fexamples\u002Fex05_sequence_classification_GRU.nim)。\n    - 训练及 [莎士比亚与简·奥斯汀风格的文本生成示例](https:\u002F\u002Fgithub.com\u002Fmratsim\u002FArraymancer\u002Fblob\u002Fv0.5.0\u002Fexamples\u002Fex06_shakespeare_generator.nim)。该示例可应用于任何基于文本的数据集（包括博客文章、LaTeX 论文和代码）。数据集至少应包含 70 万字符（0.7 MB），这已属于较小规模。\n\n- 重要修复：\n  - 修正了非单位步长卷积的形状推断问题。\n  - 兼容 nim#devel 中未来的 OpenMP 变更。\n  - GRU：之前在形状推断时会压缩所有单维度，而现在只会压缩“层”维度。\n  - 自动微分：移除了指针，以避免垃圾回收器在内存压力下移动对象时指向错误的内存区域。不幸的是…","2018-12-23T21:02:12",{"id":189,"version":190,"summary_zh":191,"released_at":192},127603,"v0.4.0","> 本次发布以帕特里克·罗斯福斯的杰作《风之名》（2007年）命名，它是“弑王者编年史”系列的第一部。\n\n变更：\n\n- 核心功能：\n  - 现已支持 OpenCL 张量！不过 Arraymancer 目前会简单地选择第一个可用的后端，可能是 CPU，也可能是 GPU。它们支持基本操作和广播操作（加法、矩阵乘法、逐元素乘法等）。\n  - 新增 `argmax` 和 `argmax_max` 过程。\n\n- 数据集：\n  - 支持从 http:\u002F\u002Fyann.lecun.com\u002Fexdb\u002Fmnist\u002F 加载 MNIST 数据集。\n  - 支持 CSV 文件的读写。\n\n- 线性代数：\n  - 最小二乘法求解器。\n  - 对称矩阵的特征值与特征向量分解。\n\n- 机器学习：\n  - 主成分分析（PCA）。\n\n- 统计学：\n  - 协方差矩阵的计算。\n\n- 神经网络：\n  - 引入了一种简短直观的语法来构建神经网络！（融合了 Keras 和 PyTorch 的风格）。\n  - 二维最大池化层。\n  - 均方误差损失函数。\n  - Tanh 和 softmax 激活函数。\n\n- 示例与教程：\n  - 使用卷积神经网络进行数字识别。\n  - 教神经网络学习 Fizzbuzz 游戏。\n\n- 工具：\n  - 通过 Python 绘制张量。\n\n此外，还包含多项与 Nim 快速开发相关的更新以及若干 bug 修复。","2018-05-05T17:15:40",{"id":194,"version":195,"summary_zh":196,"released_at":197},127604,"v0.3.0","> 本次发布以特里·古德金德的杰作《真理之剑》系列的第一部——《巫师的第一条法则》（1994年）命名。\n\n我非常激动地宣布 Arraymancer 的第三个版本发布，其中包含了大量改进、新功能，以及（不幸的是！）一些破坏性变更。\n\n警告 ⚠：由于废弃代码的过度使用及维护负担过重，所有已弃用的过程将在下一次发布中被移除。\n\n变更内容：\n- **非常** 破坏性\n  - Tensor 现在采用引用语义：`let a = b` 默认会共享数据，必须显式地进行复制。\n    - 特别是对于切片，不再需要使用 `unsafe` 过程来避免复制。\n    - `unsafe` 过程已被弃用，并将在后续版本中移除，这将使代码库和 API\u002F文档更加简洁。\n    - Tensor 和 CudaTensor 现在的工作方式相同。\n    - 使用 `clone` 来执行复制操作。\n    - Arraymancer 现在的行为与 NumPy 和 Julia 类似，使得代码移植变得更加容易。\n    - 不幸的是，这也使得调试意外的数据共享变得更加困难。\n\n- 破坏性（？）\n  - 支持的最大维度数已从 8 降低到 7，以减少缓存未命中。\n    注意，在深度学习中，3D 视频最多只需要 6 个维度：[批次, 时间, 颜色\u002F特征通道, 深度, 高度, 宽度]。\n\n- 文档\n  - 文档已完全重构，现可在以下地址查阅：https:\u002F\u002Fmratsim.github.io\u002FArraymancer\u002F\n\n- 巨大的性能提升\n  - 使用未初始化的序列。\n  - shape 和 strides 现在存储在栈上。\n  - 通过内联所有高阶函数进行优化。\n    - 提供了 `apply_inline`、`map_inline`、`fold_inline` 和 `reduce_inline` 模板。\n  - 所有高阶函数都通过 OpenMP 并行化。\n  - 整数矩阵乘法使用 SIMD、循环展开、restrict 关键字以及 64 位对齐。\n  - 在 OpenMP 归约中防止伪共享\u002F缓存争用。\n  - 移除了多个过程中的临时拷贝。\n  - 运行时检查\u002F异常现在置于 `unlikely` 宏之下。\n  - `A*B + C` 和 `C+=A*B` 会自动融合为单个操作。\n  - 不再初始化结果张量。\n\n- 神经网络：\n  - 添加了 `linear`、`sigmoid_cross_entropy` 和 `softmax_cross_entropy` 层。\n  - 添加了卷积层。\n\n- 形状变换：\n  - 添加了 `unsqueeze` 和 `stack`。\n\n- 数学：\n  - 添加了 `min`、`max`、`abs`、`reciprocal`、`negate`，以及就地的 `mnegate` 和 `mreciprocal`。\n\n- 统计：\n  - 添加了方差和标准差。\n\n- 广播：\n  - 添加了 `.^`（广播指数运算）。\n\n- CUDA：\n  - 支持卷积原语：前向和后向。\n  - 广播功能已移植到 CUDA。\n\n- 示例：\n  - 添加了感知机学习 XOR 函数的示例。\n\n- 精度：\n  - Arraymancer 在适当的情况下使用 `ln1p`（ln(1 + x)）和 `exp1m`（exp(1 - x)）过程，以避免灾难性的数值取消。\n\n- 已弃用\n  - 包含所有已弃用过程的 0.3.1 版本将于一周内发布。由于问题 https:\u002F\u002Fgithub.com\u002Fnim-lang\u002FNim\u002Fissues\u002F6436，\n    即使使用非弃用","2017-12-13T23:39:10",{"id":199,"version":200,"summary_zh":201,"released_at":202},127605,"v0.2.0","> 本次发布以特里·普拉切特的杰作《碟形世界》系列的第一部——《魔法的颜色》（1983年）命名。\n\n我非常激动地宣布 Arraymancer 的第二个版本，其中包含大量改进 `blablabla` ……\n\n话不多说：\n- 社区\n   - 现在有一个 Gitter 讨论室！\n- 重大变更\n   - `shallowCopy` 现已更名为 `unsafeView`，并接受 `let` 参数。\n   - 元素级乘法现使用 `.*`，而非 `|*|`。\n   - 向量点积现使用 `dot`，而非 `.*`。\n- 已弃用\n   - 所有张量初始化过程中的 `Backend` 参数已被弃用。\n   - `fmap` 现已更名为 `map`。\n   - `agg` 和 `agg_in_place` 现已分别替换为 `fold`，其他功能则被移除（真可惜！）\n\n- 初步支持 CUDA！！！\n   - 所有线性代数运算均已支持。\n   - 支持只读切片操作。\n   - 支持将切片转换为新的连续张量。\n\n- 张量\n   - 引入无需复制即可执行的“不安全”操作：`unsafeTranspose`、`unsafeReshape`、`unsafebroadcast`、`unsafeBroadcast2`、`unsafeContiguous`。\n   - 通过 `.+`、`.*`、`.\u002F`、`.-` 及其原地版本 `.+=`、`.-=`、`.*=`、`.\u002F=` 实现隐式广播。\n   - 新增多种形状变换操作：`squeeze`、`at` 及其“不安全”版本。\n   - 新增属性：`size`。\n   - 导出功能：`export_tensor` 和 `toRawSeq`。\n   - 聚合及按轴聚合。\n\n- 生态系统：\n   - 我要向 @edubart 致以最诚挚的感谢，感谢他测试 Arraymancer、贡献新函数，并显著提升了其整体性能。他还构建了 [arraymancer-demos](https:\u002F\u002Fgithub.com\u002Fedubart\u002Farraymancer-demos) 和 [arraymancer-vision](https:\u002F\u002Fgithub.com\u002Fedubart\u002Farraymancer-vision)，快去看看吧！你可以在张量中加载图像，并对这些图像进行逻辑回归分析呢！","2017-09-24T17:38:18",{"id":204,"version":205,"summary_zh":206,"released_at":207},127606,"v0.1.0","> 本次发布以雷蒙德·E·菲斯特的杰作《裂隙战争传奇》的第一部《魔法师：学徒》（1982年）命名。\n\n首次公开发布。\n\n包含：\n- 切片，\n- 基础线性代数运算，\n- 重塑、广播、拼接，\n- 通用函数，\n- 迭代器，\n- ……\n\n详情请参阅 README。","2017-07-12T19:34:25"]