You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fortran程序在Cray环境下使用外部输入整数分配动态数组报错

问题描述

如下Fortran代码在Intel、GNU编译器下可正常编译运行:

program simplarray
        implicit none
        real, allocatable, dimension(:,:,:) :: a
        character(len=32) :: cmdarg
        integer :: n = 0
        call get_command_argument(1, cmdarg)
        read(cmdarg,'(i)') n
        print '("n=",i5)', n
        call flush(6)
        allocate(a(n,n,2))
        print '("a is dimensioned  ", 3i5)', shape(a)
        deallocate(a)
end program

正常运行输出:

>  ./a.out 50
n=   50
a is dimensioned     50   50    2

但在Cray环境下运行报错:

> ./a.out 10
n=   10
Illegal instruction (core dumped)

如果将n改为硬编码赋值,运行正常:

integer :: n = 10
!        call get_command_argument(1, cmdarg)
!        read(cmdarg,'(i)') n

硬编码后的运行输出:

./a.out
n=   10
a is dimensioned     10   10    2

尝试从文本文件读取n的值,故障现象完全一致:

integer :: n
open(unit=11, file='size.txt')
read(11,*) n
close(11)

补充信息:

  1. 同版本12.0.3的Cray编译器在另一台Cray平台运行该程序完全正常
  2. 编译指令仅为在Intel Broadwell架构的登录节点执行:

ftn simplarray.F90


解答

问题根因

这是Cray编译环境典型的编译节点与运行节点CPU架构不兼容问题,和代码本身逻辑无关:

  • Cray的ftn编译器默认会针对当前编译所在节点的CPU架构生成最高优化等级的指令,你在Intel Broadwell架构的登录节点编译,生成的程序会用到Broadwell专属的AVX2、BMI2等扩展指令集。
  • 如果你提交运行的计算节点CPU架构比Broadwell旧(比如Haswell、Sandy Bridge等),这些专属指令无法被识别,就会抛出Illegal instruction错误。

为什么硬编码n时可以正常运行

当n是硬编码的常量时,编译器在编译阶段就能完成常量传播、数组大小计算,甚至可以把数组优化为静态分配,不会触发动态分配场景下的优化指令逻辑。只有当n是运行时动态获取的变量时,编译器会插入针对编译节点架构优化的动态内存对齐、数组维度计算的SIMD指令,这部分指令在旧架构节点无法执行。
你可以直接在编译用的登录节点运行该程序验证,大概率可以正常执行,只有提交到计算节点时才会报错。

为什么同版本编译器的另一台Cray平台无故障

那台平台的登录节点和计算节点CPU架构完全一致,编译生成的指令在运行节点可以正常支持。

解决方案

  • 编译时指定目标运行节点的CPU架构参数,示例:
    • 运行节点为Intel Haswell:ftn -xCORE-AVX2 simplarray.F90
    • 运行节点为Intel Sandy/Ivy Bridge:ftn -xAVX simplarray.F90
    • 需要兼容多代Intel架构:ftn -axCORE-AVX2,AVX,SSE4.2 simplarray.F90
  • 直接在目标计算节点上编译程序,编译器会自动适配当前节点架构生成兼容指令。

内容的提问来源于stack exchange,提问作者bob.sacamento

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 12:54:02