Search Unity

Burst 1.5.0-pre.5 - function pointers not working

Discussion in 'Burst' started by korzen303, Feb 25, 2021.

  1. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    223
    Hello @xoofx,

    in the latest preview .5 the function pointers stopped working. Of course the BurstCompile attribute is both on class and method and worked just fine in previous previews.

    Thanks
     
  2. sheredom

    sheredom

    Unity Technologies

    Joined:
    Jul 15, 2019
    Posts:
    300
    Can I check a few things?
    • Are you using an explicit `CompileFunctionPointer` to compile this, or relying on the newer direct call method?
    • Did you do an editor restart after updating the package?
     
  3. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    223
    Hi @sheredom

    yeah, I am using CompileFunctionPointer in a usual way, see below. I restarted the editor.
    Like I mentioned this worked fine in all previous 1.5 Burst previews. The problem occurs in two separate projects in 2020.2.5f1 and 2021.1.0b9.

    And regarding the direct calls, these never worked for me in all 1.5 previews when called from non-MainThread, which is essential for me. I will make a separate bug report for this though.

    Code (CSharp):
    1. [BurstCompile]
    2. public unsafe  class DefKitPositionBasedDynamicsSystem : MonoBehaviour
    3. {
    4.  
    5.     unsafe delegate void Integrate(float dt, int pointsCount, Vector4* positions, Vector4* predictedPositions, Vector4* velocities, float* invMasses);
    6.  
    7.     Integrate cachableDelegate;
    8.  
    9.     [BurstCompile]
    10.     [AOT.MonoPInvokeCallback(typeof(Integrate))]
    11.     unsafe static void IntegrateBurst(float dt, int pointsCount, Vector4* positions, Vector4* predictedPositions, Vector4* velocities, float* invMasses)
    12.     {
    13.         float dtInv = 1.0f / dt;
    14.         for (int i = 0; i < pointsCount; i++)
    15.         {
    16.             if (invMasses[i] != 0.0)
    17.             {
    18.                 velocities[i] = (predictedPositions[i] - positions[i]) * dtInv;
    19.                 positions[i] = predictedPositions[i];
    20.  
    21.             }
    22.         }
    23.     }
    24.  
    25.  
    26.  
    27.     // Use this for initialization
    28.     void Start()
    29.     {
    30.  
    31.         this.cachableDelegate = BurstCompiler.CompileFunctionPointer<Integrate>(IntegrateBurst).Invoke;
    32.  
    33.     }
    34.  
    35.     void Update()
    36.     {
    37.         cachableDelegate(dt, body.count, body.positionsNativePtr, body.predictedPositionsNativePtr, body.velocitiesNativePtr, body.massesInvNativePtr);
    38.     }
    39. }
     
  4. sheredom

    sheredom

    Unity Technologies

    Joined:
    Jul 15, 2019
    Posts:
    300
    1.5 will ship with DirectCall having to be called from the main-thread - we'll try and enable it to work from other threads in 1.6.

    I had to modify your code above slightly:

    Code (CSharp):
    1. using UnityEngine;
    2. using Unity.Burst;
    3.  
    4. [BurstCompile]
    5. public unsafe class NewBehaviourScript : MonoBehaviour
    6. {
    7.     unsafe delegate void Integrate(float dt, int pointsCount, Vector4* positions, Vector4* predictedPositions, Vector4* velocities, float* invMasses);
    8.  
    9.     Integrate cachableDelegate;
    10.  
    11.     [BurstCompile]
    12.     [AOT.MonoPInvokeCallback(typeof(Integrate))]
    13.     static void IntegrateBurst(float dt, int pointsCount, Vector4* positions, Vector4* predictedPositions, Vector4* velocities, float* invMasses)
    14.     {
    15.         float dtInv = 1.0f / dt;
    16.         for (int i = 0; i < pointsCount; i++)
    17.         {
    18.             if (invMasses[i] != 0.0)
    19.             {
    20.                 velocities[i] = (predictedPositions[i] - positions[i]) * dtInv;
    21.                 positions[i] = predictedPositions[i];
    22.             }
    23.         }
    24.     }
    25.  
    26.  
    27.  
    28.     // Use this for initialization
    29.     void Start()
    30.     {
    31.         IntegrateBurst(42, 0, null, null, null, null);
    32.         this.cachableDelegate = BurstCompiler.CompileFunctionPointer<Integrate>(IntegrateBurst).Invoke;
    33.     }
    34.  
    35.     void Update()
    36.     {
    37.         cachableDelegate(42, 0, null, null, null, null);
    38.     }
    39. }
    40.  
    But this worked for me in a scene (I just attached that script to the main camera in a dud scene, attached unity debugger to be sure the compile got hit).

    I also tried a player build, worked there too.
     
    DreamingImLatios likes this.
  5. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    223
    Thanks @sheredom for checking this. It worked indeed but so did the code I posted in the first place:)

    However, I kept digging and it turned out that if you add ANY, even unrelated, [DllImport] on top you will get the Burst Atrribute missing error:


    Code (CSharp):
    1. using UnityEngine;
    2. using Unity.Burst;
    3. using System.Runtime.InteropServices;
    4. [BurstCompile]
    5. public unsafe class NewBehaviourScript : MonoBehaviour
    6. {
    7. #region ADDED
    8.  
    9.         [DllImport("DefKit")]
    10.         public unsafe static extern void PredictPositions_native(float dt, float damping, int pointsCount, Vector4* positions, Vector4* predictedPositions, Vector4* velocities, Vector4* forces, float* invMasses, Vector4[] gravity);
    11.  
    12. #endregion
    13.  
    14.     unsafe delegate void Integrate(float dt, int pointsCount, Vector4* positions, Vector4* predictedPositions, Vector4* velocities, float* invMasses);
    15.     Integrate cachableDelegate;
    16.     [BurstCompile]
    17.     [AOT.MonoPInvokeCallback(typeof(Integrate))]
    18.     static void IntegrateBurst(float dt, int pointsCount, Vector4* positions, Vector4* predictedPositions, Vector4* velocities, float* invMasses)
    19.     {
    20.         float dtInv = 1.0f / dt;
    21.         for (int i = 0; i < pointsCount; i++)
    22.         {
    23.             if (invMasses[i] != 0.0)
    24.             {
    25.                 velocities[i] = (predictedPositions[i] - positions[i]) * dtInv;
    26.                 positions[i] = predictedPositions[i];
    27.             }
    28.         }
    29.     }
    30.     // Use this for initialization
    31.     void Start()
    32.     {
    33.         IntegrateBurst(42, 0, null, null, null, null);
    34.         this.cachableDelegate = BurstCompiler.CompileFunctionPointer<Integrate>(IntegrateBurst).Invoke;
    35.     }
    36.     void Update()
    37.     {
    38.         cachableDelegate(42, 0, null, null, null, null);
    39.     }
    40. }
    41.  
     
  6. sheredom

    sheredom

    Unity Technologies

    Joined:
    Jul 15, 2019
    Posts:
    300
    Oh nice find, I can repro this! Will start digging :)
     
  7. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    223
    Thanks @sheredom!
    it would be great to have a possibility to launch as well as schedule "ParallelFor" Bursted Jobs from non-MainThread. I mean to have something like a raw, bare-bone JobSystem without any safety-systems, which could be used on it's own, separately from Unity's MainThread JobSystem. Maybe it could share the same task queue with the Main JobSystem for performance reasons though. I know that I could use Task Parallel Library, but having a single code-base for both MainThread and non-MainThread cases would be great. Here is my concrete application for such appraoch https://forum.unity.com/threads/scheduling-jobs-from-not-a-mainthread.569866/#post-4861184
    Cheers
     
  8. sheredom

    sheredom

    Unity Technologies

    Joined:
    Jul 15, 2019
    Posts:
    300
    Think I've got a fix - once again thanks for the bug report!

    Should be in the next 1.5 prerelease.

    I'll raise the scheduling on non-main-thread elsewhere.

    Specifically for the direct call stuff - it'll work from any thread in 1.6 like I said, its just an API limitation we're stuck with in 1.5 that means we can only support it from the main thread.
     
  9. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    223
  10. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    223
    Hi @sheredom, thanks a lot for fixing this in 1.5! It is working fine now.
     
    sheredom likes this.
  11. sheredom

    sheredom

    Unity Technologies

    Joined:
    Jul 15, 2019
    Posts:
    300
    Awesome! Thanks for filing the bug, we really appreciate when any of our users take the time to make Burst better :)
     
  12. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    223
    Hi @sheredom, no problem, always happy to help. Soo... now that the Burst 1.5 is out any plans to support scheduling "unsafe" jobs from non-main thread? The function pointers are nice and performant but I still need to maintain the same code twice: Jobs for non-hardware applications and equivalent static functions for hardware ticked usage.
    Thanks
     
  13. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    What @sheredom meant is - he'll raise the issue with the team making the job system, scheduling is really out of scope for Burst. You may want to post the feature request on DOTS/jobs forums to try to get some traction yourself too.
     
  14. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    223