Skip to content

Strange Illegal Instruction: 4 (mac) or SIGSEGV (linux) on array code in "main" proc #7349

@mratsim

Description

@mratsim

cc @narimiran

The following throws Illegal instruction: 4 on my Mac in normal and release compilation mode.
It throws SIGSEGV on narimiran Manjaro Linux

import math, times, strformat

const
  dz = 0.01
  z = 100
  spaceSteps = int(z / dz)
  timeSteps = 10000
  dt = 0.12 / timeSteps
  alpha = 2.0
  startingTemp = 30.0
  oscillations = 20.0


proc f(T: array[spaceSteps, float]): array[spaceSteps-2, float] =
  for i in 0 .. spaceSteps-3:
    result[i] = alpha * (T[i] - 2.0 * T[i+1] + T[i+2]) / dz^2


proc eulerSolve(Ts: var array[timeSteps, array[spaceSteps, float]]) =
  for t in 0 ..< timeSteps-1:
    let
      k = f(Ts[t])
    for i in 1 .. spaceSteps-2:
      Ts[t+1][i] = Ts[t][i] + dt * k[i-1]
    Ts[t+1][spaceSteps-1] = Ts[t+1][spaceSteps-2]

proc main() =
  var Ts: array[timeSteps, array[spaceSteps, float]]

  for t in 0 ..< timeSteps:
    Ts[t][0] = startingTemp - oscillations * sin(2.0 * PI * t.float / timeSteps)
    for s in 1 ..< spaceSteps:
      Ts[t][s] = startingTemp

  Ts.eulerSolve()


let start = cpuTime()
main()
let stop = cpuTime()

let elapsed = stop - start
echo &"Native array Euler solve - time taken: {elapsed} seconds”

What is strange is that putting everything in a global context works:

import math, times, strformat

const
  dz = 0.01
  z = 100
  spaceSteps = int(z / dz)
  timeSteps = 10000
  dt = 0.12 / timeSteps
  alpha = 2.0
  startingTemp = 30.0
  oscillations = 20.0


proc f(T: array[spaceSteps, float]): array[spaceSteps-2, float] =
  for i in 0 .. spaceSteps-3:
    result[i] = alpha * (T[i] - 2.0 * T[i+1] + T[i+2]) / dz^2


proc eulerSolve(Ts: var array[timeSteps, array[spaceSteps, float]]) =
  for t in 0 ..< timeSteps-1:
    let
      k = f(Ts[t])
    for i in 1 .. spaceSteps-2:
      Ts[t+1][i] = Ts[t][i] + dt * k[i-1]
    Ts[t+1][spaceSteps-1] = Ts[t+1][spaceSteps-2]

# proc main() =
#   var Ts: array[timeSteps, array[spaceSteps, float]]

#   for t in 0 ..< timeSteps:
#     Ts[t][0] = startingTemp - oscillations * sin(2.0 * PI * t.float / timeSteps)
#     for s in 1 ..< spaceSteps:
#       Ts[t][s] = startingTemp

#   Ts.eulerSolve()


let start = cpuTime()
#main()

var Ts: array[timeSteps, array[spaceSteps, float]]

for t in 0 ..< timeSteps:
  Ts[t][0] = startingTemp - oscillations * sin(2.0 * PI * t.float / timeSteps)
  for s in 1 ..< spaceSteps:
    Ts[t][s] = startingTemp

Ts.eulerSolve()
let stop = cpuTime()

let elapsed = stop - start
echo &"Native array Euler solve - time taken: {elapsed} seconds”

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions