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

CPU Overload When Using Many Functions #4437

Open
jgomez720 opened this issue Nov 8, 2024 · 12 comments
Open

CPU Overload When Using Many Functions #4437

jgomez720 opened this issue Nov 8, 2024 · 12 comments
Labels
bug Something isn't working

Comments

@jgomez720
Copy link
Collaborator

jgomez720 commented Nov 8, 2024

Description

When I was trying to import many functions, my computer had a CPU overload. App clicking became unresponsive.

edit: does not have to do with import, it's just using many functions.

Version

v0.26.3

Recordings/Screenshots

Screenshare.-.2024-11-08.12_09_20.AM.mp4

KCL

whatever.kcl

import nas1351N306, nas1351N308, nas1351N310, nas1351N312, nas1351N316, nas1351N320, nas1351N324, nas1351N328, nas1351N332, nas1351N336, nas1351N340, nas1351N344, nas1351N348, nas1351N364 from 'nas1351.kcl'

plane001 = {
    plane: {
      origin: [0.0, 0.0, 0.0],
      xAxis: [1.0, 0.0, 0.0],
      yAxis: [0.0, 1.0, 0.0],
      zAxis: [0.0, 0.0, 1.0]
    }
  }

nas1351N312(plane001)

nas1351.kcl

export fn nas1351N306 = (plane) => {

  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = 3 / 8
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}

export fn nas1351N308 = (plane) => {

  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = 1 / 2
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}
  
export fn nas1351N310 = (plane) => {

  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = 5 / 8
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}

export fn nas1351N312 = (plane) => {

  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = 0.75
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}

export fn nas1351N314 = (plane) => {

  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = 7 / 8
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}

export fn nas1351N316 = (plane) => {

  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = 1.00
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}

export fn nas1351N320 = (plane) => {

  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = 1.25
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}

export fn nas1351N324 = (plane) => {

  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = 1.5
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}

export fn nas1351N328 = (plane) => {

  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = 1.75
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}

export fn nas1351N332 = (plane) => {

  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = 2.00
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}

export fn nas1351N336 = (plane) => {

  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = 2.25
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}

export fn nas1351N340 = (plane) => {

  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = 2.50
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}

export fn nas1351N344 = (plane) => {

  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = 2.75
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}

export fn nas1351N348 = (plane) => {

  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = 3.00
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}

export fn nas1351N364 = (plane) => {

  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = 4.00
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}
@jgomez720 jgomez720 added the bug Something isn't working label Nov 8, 2024
@jtran
Copy link
Collaborator

jtran commented Nov 8, 2024

  1. I copied nas1351.kcl to a new file a-no-exports.kcl. (I used “a” so that it would sort to the top and load first.)
  2. Remove all exports.
  3. Reload the app and go to this new file.

I experienced similar slowness. So I think it’s unrelated to imports.

Can you confirm, @jgomez720?

@jgomez720
Copy link
Collaborator Author

jgomez720 commented Nov 8, 2024

I can confirm. I removed all exports, did a refresh in the nas1351.kcl file, and got a CPU overload.
Who should I throw this over to?

@jgomez720 jgomez720 changed the title CPU Overload When Importing Many Functions CPU Overload When Using Many Functions Nov 12, 2024
@jtran
Copy link
Collaborator

jtran commented Nov 19, 2024

We tried reducing the KCL a bit.

The part doesn't render in the scene when using an import. The same thing with everything inlined in a single file works, but it's not consistent. I think some kind of timeout is being hit. If I reduce the imported functions to only one, and gradually add them, it works.

For a brief second, this error shows up in the editor and then disappears.

Image

This is what the error looks like when doing break on uncaught exceptions. Seems to be inside WASM, so the back trace isn't too helpful.

Image

// y-main.kcl

import nas1351N306, nas1351N308, nas1351N310, nas1351N312, nas1351N316, nas1351N320, nas1351N324, nas1351N328, nas1351N332, nas1351N336, nas1351N340, nas1351N344, nas1351N348, nas1351N364 from 'b-simple-fasteners.kcl'

plane001 = {
  plane: {
    origin: [0.0, 0.0, 0.0],
    xAxis: [1.0, 0.0, 0.0],
    yAxis: [0.0, 1.0, 0.0],
    zAxis: [0.0, 0.0, 1.0]
  }
}

nas1351N312(plane001)

// b-simple-fasteners.kcl

fn makeFastener = (plane, length) => {
  // constants
  boltHeadHeight = 0.19
  boltHeadDiameter = 0.312
  boltDiameter = 0.19
  boltLength = length
  hexWidth = 0.156

  wallLength = hexWidth / (2 * sin(toRadians(60)))
  hexStartY = wallLength / 2 + hexWidth / 2 * sqrt(3)

  // screw head
  sketch001 = startSketchOn(plane)
    |> circle({
         center: [0, 0],
         radius: boltHeadDiameter / 2
       }, %)
  extrude001 = extrude(boltHeadHeight, sketch001)

  // hex hole
  sketch002 = startSketchOn(extrude001, 'END')
    |> startProfileAt([hexWidth / 2, 0], %)
    |> yLine(-wallLength / 2, %)
    |> angledLine({ angle: 210, length: wallLength }, %)
    |> angledLine({ angle: 150, length: wallLength }, %)
    |> yLine(wallLength, %)
    |> angledLine({ angle: 30, length: wallLength }, %)
    |> angledLine({ angle: -30, length: wallLength }, %)
    |> close(%)
  extrude002 = extrude(-boltHeadHeight * 0.7, sketch002)

  // bolt extrude
  sketch003 = startSketchOn(extrude001, 'START')
    |> circle({ center: [0, 0], radius: boltDiameter/2 }, %)
  
  extrude003 = extrude(boltLength, sketch003)

  return extrude003
}

export fn nas1351N306 = (startPlane) => {
  return makeFastener(startPlane, 3 / 8)
}
export fn nas1351N308 = (startPlane) => {
  return makeFastener(startPlane, 1/2)
}
export fn nas1351N310 = (startPlane) => {
  return makeFastener(startPlane, 5/8)
}
export fn nas1351N312 = (startPlane) => {
  return makeFastener(startPlane, 3/4)
}
export fn nas1351N314 = (startPlane) => {
  return makeFastener(startPlane, 7/8)
}
export fn nas1351N316 = (startPlane) => {
  return makeFastener(startPlane, 1.00)
}
export fn nas1351N320 = (startPlane) => {
  return makeFastener(startPlane, 1.25)
}
export fn nas1351N324 = (startPlane) => {
  return makeFastener(startPlane, 1.5)
}
export fn nas1351N328 = (startPlane) => {
  return makeFastener(startPlane, 1.75)
}
export fn nas1351N332 = (startPlane) => {
  return makeFastener(startPlane, 2.00)
}
export fn nas1351N336 = (startPlane) => {
  return makeFastener(startPlane, 2.25)
}
export fn nas1351N340 = (startPlane) => {
  return makeFastener(startPlane, 2.5)
}
export fn nas1351N344 = (startPlane) => {
  return makeFastener(startPlane, 2.75)
}
export fn nas1351N348 = (startPlane) => {
  return makeFastener(startPlane, 3.00)
}
export fn nas1351N364 = (startPlane) => {
  return makeFastener(startPlane, 4.00)
}

@TomPridham
Copy link
Contributor

I haven't tracked down the actual problem yet, but running that sample with debug symbols show the panic is happening here:

JsValue::from_serde(&exec_state).map_err(|e| e.to_string())
. The actual panic comes from trying to convert incomplete JSON. It seems like something is OOMing which ends up only sending a partial of the ExecState to serde and is thus invalid. Something about the representation of the ExecState seems to be really space inefficient. I printed the ExecState from that program in a test and wrote the output to a file and it was almost 1GB. This is probably a decent bit larger than the actual size since it includes all the struct names in the debug output, but even so, that's gigantic. Printing just the AST generated from the program is like 30KB. The increase also doesn't seem to be linear. I removed functions so that there were only the number of exports in the kcl as in the filename, e.g. out_4.txt only had the first 4 exports, out_8.txt had 8, etc.
Image
It seems like each function might be getting a copy of the AST at the time of parsing included in its memory

@TomPridham
Copy link
Contributor

memory: Box::new(exec_state.memory().clone()),
is the culprit. replacing that line with a ProgramMemory::default() drops the output file to 89KB. Not sure what the best way to capture the current state without completely copying the entire AST is

@jtran
Copy link
Collaborator

jtran commented Dec 24, 2024

Yes, thank you for digging into this and getting more details. I knew it was bad, but I didn't know how bad.

As a band-aid, I had the idea of clearing closed over program memory in closures before crossing back to TS from WASM, just before the line you linked in wasm.rs. As far as I know, it's never used on the TS side.

But I want to make sure the linked issue #4857 is fixed first. Even if there's ever a panic on the WASM side, the TS side should handle it gracefully.

@jtran
Copy link
Collaborator

jtran commented Dec 29, 2024

See:

CPU still gets high load and is slow, but the file no longer fails.

@TomPridham
Copy link
Contributor

Not sure if it would be easier to add #[serde(skip] above this line

memory: Box<ProgramMemory>,
. If that stuff needs to get serialized elsewhere, that's prolly not a good solution

@jtran
Copy link
Collaborator

jtran commented Jan 2, 2025

That is a clever approach that would have a much smaller diff. It might also make it easier to avoid serializing closure memory recursively, which my branch doesn't yet do. I would consider adding the skip to my branch.

I've thought about it, and I think we'd be better off with a separate type like ExecOutcome in my branch. This will force us to opt-in to make new fields available to the TS side, rather than exposing everything by default. I'm hoping it may also allow us to reduce the number of derives needed for Rust types. As it is, everything in ExecState needs to implement all the traits that the TS side needs, even though only a few things are used on the TS side.

We'd also like to reduce what we expose to TS, so that we can change things on the Rust side easier. The hope is to not expose ProgramMemory in the future. But we're still working on the alternative.

I closed my PR because it has a problem. See comments there.

@jtran
Copy link
Collaborator

jtran commented Jan 4, 2025

@TomPridham
Copy link
Contributor

Yeah, I was mainly thinking it would be nice not to have to worry about clearing all the recursive memory manually. Just not sending that stuff back sounds like a better alternative if it isn't used on the TS side

@jtran
Copy link
Collaborator

jtran commented Jan 9, 2025

About the cloning of ProgramMemory that you linked...

memory: Box::new(exec_state.memory().clone()),

The reason for the clone of ProgramMemory is because we implement it with mutable HashMaps where we look up variables by name. This is simple, but it's not great performance-wise and can cause issues like this. See test_function_cannot_access_future_definitions in src/wasm-lib/kcl/src/execution/mod.rs and other tests I added in #3015.

I wanted to mention another related thing that was talked about:

The above issue would help here (by reducing serialization and reducing data crossing the WASM boundary) and make progress towards other goals. But without addressing the cloning, it's unclear if it would solve the CPU overload problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants