Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add fuseLoops macro to fuse loops in Nim #20

Merged
merged 4 commits into from
Jun 16, 2024
Merged

add fuseLoops macro to fuse loops in Nim #20

merged 4 commits into from
Jun 16, 2024

Conversation

Vindaar
Copy link
Member

@Vindaar Vindaar commented Jun 16, 2024

Fusing the loops in this context means the equivalent of OpenMP's collapse statement, i.e. merging multiple nested loops into a single loop.

One can use the nofuse argument to indicate a nested loop should not be fused.

The following code shows the essentials:

fuseLoops:
  for i in 0 ..< N:
    let x = i * 2
    for j in 0 ..< T:
      let z = x * j
      echo i, j, x, z
    echo x
# Becomes:
# for idx_553648168 in 0 ..< N * T:
#   let i = idx_553648168 div T
#   let j = idx_553648168 mod T
#   let x = i * 2
#   let z = x * j
#   echo i, j, x, z
#   echo x


fuseLoops:
  for i in 0 ..< N:
    let x = i * 2
    for j in 0 ..< T:
      let z = x * j
      echo i, j, x, z
      for k in nofuse(0 ..< T):
        echo k
    echo x
# Becomes:
# for idx_553648190 in 0 ..< N * T:
#   let i = idx_553648190 div T
#   let j = idx_553648190 mod T
#   let x = i * 2
#   let z = x * j
#   echo i, j, x, z
#   for k in nofuse(0 ..< T):
#     echo k
#   echo x

fuseLoops("parallel for"):
  for i in 0 ..< N:
    let x = i * 2
    for j in 0 ..< T:
      let z = x * j
      for k in 0 ..< X:
        echo i, j, k, x, z
    echo x
# Becomes:
# for idx_553648204 in `||`(0, N * (T * X), "parallel for"):
#   let i = idx_553648204 div X * T
#   let j = idx_553648204 mod X * T div X
#   let k = idx_553648204 mod X * T mod X
#   let x = i * 2
#   let z = x * j
#   echo i, j, k, x, z
#   echo x

## The following raises a CT error
when compiles((
  fuseLoops:
    for i in 0 ..< N:
      let x = i * 2
      var zsum = 0
      for j in 0 ..< T:
        let z = x * j
        zsum += z
        echo i, x, z
      echo x
      for j in 0 ..< 2 * T:
        zsum += j
      echo zsum
)):
  doAssert false

@Clonkk
Copy link
Member

Clonkk commented Jun 16, 2024

we should export fuse_loops in root scinim :)

Fusing the loops in this context means the equivalent of OpenMP's
`collapse` statement, i.e. merging multiple nested loops into a single
loop.

One can use the `nofuse` argument to indicate a nested loop should
_not_ be fused.
@Vindaar
Copy link
Member Author

Vindaar commented Jun 16, 2024

Merging despite CI failures. At least the CI failures are now different! 🤣

@Vindaar Vindaar merged commit 95e301c into main Jun 16, 2024
0 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants