"PR: unreviewed" forgotten

Summary
The bot forgot (a few times) to remove the PR: unreviewed either when it was mistakenly added alongside PR: reviewed-approved (shouldn't that label be PR: review-approved?) like in here or and simply forgot to remove it when a review was approved or changes were requested.
Steps to reproduce
Have someone or a bot open a PR, have a bot (say access-lint) approve the review and watch.
Pull Request URL
What is the current bug's behaviour?
It seems to be activating two events causing a mix of labelling which could persist even after the PR was closed or merged.
What is the expected correct behaviour?
The bot should add and remove the correct label whether a bot or human approved a PR or requested changes to it.
Relevant logs and/or screenshots
There are other repos where that bug occurred but it can be reflected by the example above.
Possible fixes
Possibly adding more checks to ensure that PRs, where multiple reviews are requested that it takes into account when one is an approval and the other one, is either blank (read unreviewed) or requesting changes.

@Berkmann18 Thank you for the detailed explanation. I will look the issue deeply on this weekend.

@Berkmann18 I have not looked into it because I was tied up. I would appreciate if you could create a pull request to fix this issue.

@sotayamashita Okay, no problem.
I'll have a go (although the private key can't be found when running npm run start:dev).

@Berkmann18 Let me create a guide for your contribution.

@sotayamashita I've looked at the CONTRIBUTING.md file but it seems that the .env file doesn't work properly or if I missed a bit on where the private key should be and what name it should have despite the fact that the cat ... command work on the CLI.

@Berkmann18
If you run the App, you do not load the private key in .env.  I have updated the CONTRIBUTION.md. I hope it helps you.


[Java] Parallel to build JNI C++ code

Describe the enhancement requested
Now we use
<executable>cmake</executable>
<commandlineArgs>--build cpp-jni --target install --config Release</commandlineArgs>

The CI use export CMAKE_BUILD_PARALLEL_LEVEL=NUM_THREAD to accelerate build process.
But user may not set this environment.
I would prefer to dd -j to commandlineArgs
-j [<jobs>], --parallel [<jobs>]
New in version 3.12.

The maximum number of concurrent processes to use when building. If <jobs> is omitted the native build tool's default number is used.

The [CMAKE_BUILD_PARALLEL_LEVEL](https://cmake.org/cmake/help/latest/envvar/CMAKE_BUILD_PARALLEL_LEVEL.html#envvar:CMAKE_BUILD_PARALLEL_LEVEL) environment variable, if set, specifies a default parallel level when this option is not given.

Some native build tools always build in parallel. The use of <jobs> value of 1 can be used to limit to a single job.

https://cmake.org/cmake/help/latest/manual/cmake.1.html#build-tool-mode
If you think it is possible, I can help to implement it.
Component(s)
Java

@jinchengchenghh nice suggestion, happy to see a contribution.


Better align TypeScript type checking in web-forms, .vue modules

As I've been reviewing #183, trying a change I want to suggest produced a very surprising type for a destructured array member. What surprised me is that I expected it to be string | undefined, but it is not!
As it turns out, the TypeScript configurations in @getodk/web-forms are much less strict than throughout the rest of the project. We should make these consistent. We should also consider sharing a great deal more between configs so it's less likely for discrepancies like this to occur.

We probably want to align more, but these definitely stand out:

strict should be true
noUncheckedIndexedAccess, which is oddly not part of the strict catch-all, should also be true


pages/index.js fails to update imports

Describe the bug
While restructuring the code, I tried to re-run the app, only to find the following error: "ReferenceError: RadixThemesHeading is not defined"
To Reproduce
I am not sure how the error can be reproduced. What worked for me is:

Rewrote some code in a different file and imported it into the reflex_app.py file for rendering.
Ran the reflex run command

Expected behavior
The app should have simply run as normal, producing the exact same output as before refactoring of the code.
Screenshots

Specifics (please complete the following information):

Python Version: 3.11.8
Reflex Version: 0.4.4
OS: macOS Sonoma 14.2.1
Browser (Optional): Chrome

Additional context
The pages/index.py file should automatically update the imports to re-render the app. In my case, the RadixThemesHeading and RadixThemesText from the '@radix-ui/themes' were not automatically updated and had to be done manually.

are you using @rx.memo?

are you using @rx.memo?

No, but I created custom components to render different parts of the web page, in the 'React style'. To create these components, I created a separate file and declared a class that extends rx.Component. Inside this class I defined a render function that renders the required component. When I do this, and execute reflex run, the pages/index.js did not correctly update the imports. This was the source of error.

Can you show the code of your custom rx.Component subclass?
Custom components do need to declare their imports, so that reflex knows what imports to include in the page when the component is rendered. Typically a higher-order component would just be a python function that returns a composition of other components. If I see your code, I can make a more specific recommendation.

Can you show the code of your custom rx.Component subclass?
Custom components do need to declare their imports, so that reflex knows what imports to include in the page when the component is rendered. Typically a higher-order component would just be a python function that returns a composition of other components. If I see your code, I can make a more specific recommendation.

Sure. Here's how I created the custom class:
reflex_app/my_component.py
`import reflex as rx
class MyComponent(rx.Component):
def render() -> rx.Component:
# My code here
`
reflex_app/reflex_app.py:
`
import reflex as rx
from . import my_component.MyComponent
def index() -> rx.Component:
return MyComponent()
app = rx.App()
app.add_page(index)
`

what is the # My code here part though?
if you look at the Component.render function in the base class, it does not return a component. It's supposed to return a render dict.
If you want to return a Component, then you should override the classmethod Component.create and return the Component from there. Alternatively you can just define a regular function that returns a Component and use that.
def MyComponent(name: str) -> rx.Component:
    return rx.vstack(
        rx.text("Hello"),
        rx.text(name),
    )

what is the # My code here part though?
if you look at the Component.render function in the base class, it does not return a component. It's supposed to return a render dict.
If you want to return a Component, then you should override the classmethod Component.create and return the Component from there. Alternatively you can just define a regular function that returns a Component and use that.
def MyComponent(name: str) -> rx.Component:
    return rx.vstack(
        rx.text("Hello"),
        rx.text(name),
    )

This is the code that I got from the AI in the documentation:
reflex_app/my_component.py
class MyComponent(rx.Component):
    def render() -> rx.Component:
        return rx.Box(
             # other code
        )

reflex_app/reflex_app.py
import reflex as rx
from . import my_component

def index() -> rx.Component:
    return my_component.MyComponent()

app = rx.App()
app.add_page(index)

The above two codes reproduce the error that I mentioned in the beginning. Is this the wrong way to create a component?

@atishpanday Check out our component documentation - you don't need to subclass rx.Component when defining your UI.

@atishpanday Please refer to the specified docs as pointed out. Closing this issue for now. Feel free to reopen or raise another issue when you encounter other issues.


[framework7-svelte] MessagebarSheetImage: no background-url style

This commit removed style attribute from src/svelte/components/messagebar-sheet-image.svelte that is used for background-image on attachment.
You can check it on documentation site:
https://framework7.io/svelte/messagebar.html

closing as fixed a while ago


[Bug] Copying TXID information only copy/pastes part of the TX and it is truncated

What happened?
You can see how it truncates the 3 fields in the address bar on my screenshot, not sure if this is in the list of your fixes that are waiting to be published to be implemented or not, incase it is not i am logging it here. Happens in both full screen and not full screen mode

Version
2.0.0
What platform are you using?
Windows
What browser are you using?
Chrome
Is this a trezor issue?
No
Relevant log output
No response

Thanks a lot for reporting it @nrhs05 !
We implemented a fix on this commit, on our develop branch:
https://github.com/syscoin/pali-wallet/commit/3bf87c1b519817b781ec2a5d53601278d902ee6e
We will be updating it on the Browsers Extension stores by the end of next week along with other fixes. (We will also start creating tags on GitHub with proper changelogs, from this next release and all the next ones so keep posted for it).


Fix typos in XML element names

I've updated this in the code generator and pushed out the changes. Thanks for bringing this issue to our attention.


Display preview when hovering over an image

Al pasar con el cursor por los archivos de (videos, imagenes, etc) aparezca una vista previa
Hovering over files (videos, images, etc.) displays a preview

Quick Look integration is planned for v0.7

QuickLook integration has been released. Make sure to check it out and let us know if there are any issues.


Speed-up pipeline for 7B model

The pipeline is running fast but is still significantly slower than the 1B model (10x slower at the time of writing) which harms our ability to run experiments on the larger models sizes. We want to explore options to speed this up including;

gradient accumulation
multi-node sharding setups with deepspeed
lower batch sizes for speed in forward pass
read NeoX paper

this has been completed and achieved 55% speedup


Should  json sorting be a source action instead of a setting

Testing #191455
Should json.sortOnSave.enable be exposed using a code action (specifically a source action) instead of as a setting? Some advantages:

We can reuse the existing editor.codeActionsOnSave setting instead of adding a new one
Sorting will play nicer with other source actions since users can configure the order in which the actions run
Users can trigger source actions through the source action context menu or with keybindings

Hey @mjbvz, that's a good idea! I'll take note of it for implementation later

Yes, makes sense!


add humhub as installable and upgradeable Software

Somehow yarn readme:generate threw some newlines into the mix which were not there before?
for example:
 -  -p, --project-id=<value>  ID or short ID of a project; this flag is optional if a default project is set in the context
+  -p, --project-id=<value>
+
+    ID or short ID of a project; this flag is optional if a default project is set in the context

     May contain a short ID or a full ID of a project; you can also use the "mw context set --project-id=<VALUE>" command
     to persistently set a default project for all commands that accept this flag.

if I read the linter correctly. but the yarn scripts have not been touched?

Somehow yarn readme:generate threw away some newlines? for example:
 -  -p, --project-id=<value>  ID or short ID of a project; this flag is optional if a default project is set in the context
+  -p, --project-id=<value>
+
+    ID or short ID of a project; this flag is optional if a default project is set in the context

     May contain a short ID or a full ID of a project; you can also use the "mw context set --project-id=<VALUE>" command
     to persistently set a default project for all commands that accept this flag.

if I read the linter correctly. but the yarn scripts have not been touched?

I think this might be related to the oclif dependency having been bumped recently; have you made sure your node_modules are up-to-date?


proper prerequisites  for creating react app

node version,
npm version
May can add node website link, and version number.

You can read clear all your doubts here. [(https://github.com/reactjs/reactjs.org#readme)]


Dependabot Runs successfully, Fails to create PR with /git/trees: 422 - GitRPC::BadObjectState

Is there an existing issue for this?

[X] I have searched the existing issues

Package ecosystem
https://github.com/actions/runner-images/blob/ubuntu22/20240721.1/images/ubuntu/Ubuntu2204-Readme.md
Package manager version
Pip3 22.0.2
Language version
python 3.12.x
Manifest location and content before the Dependabot update
/pip-requirements.txt
dependabot.yml content
dependabot.yml
Updated dependency
+-------------------------------------------------------------+
|             Changes to Dependabot Pull Requests             |
+---------+---------------------------------------------------+
| created | edk2-pytool-library ( from 0.21.5 to 0.21.8 )     |
| created | edk2-pytool-extensions ( from 0.27.4 to 0.27.10 ) |
+---------+---------------------------------------------------+
What you expected to see, versus what you actually saw
Dependabot runs with success, and it lists the correct PRs to update, but fails to create the PR, and shows an error message 3 minutes after the run completes. The error message is below.
Dependabot failed to create a pull request
Dependabot ran into an issue when attempting to create the pull request
Dependabot encountered the following error:
POST https://api.github.com/repos/microsoft/mu_tiano_platforms/git/trees: 422 - GitRPC::BadObjectState // See: https://docs.github.com/rest/git/trees#create-a-tree
Troubleshoot Dependabot errors
Native package manager behavior
No issues.
Images of the diff or a link to the PR, issue, or logs
https://github.com/microsoft/mu_tiano_platforms/actions/runs/10073577332/job/27847909464
Smallest manifest that reproduces the issue
No response

Is there any other information that is needed to start looking into this?
Dependency updates have been blocked for close to 2 months on this repo, while the other repos using dependabot are working correctly.

Just started hitting this issue in the last day or so...

Are there any updates that be shared?

We have the same issue, whenever we introduce groups to our dependabot config it shows the following errors:

When we remove the groups, then it has 0 errors and all PRs are created


ORNL Titan: Deadlock when lists the events with PAPI enabled

branch: master
/opt/cray/modulefiles/papi/<IP_ADDRESS>:
Linux titan-ext4 3.0.101-<IP_ADDRESS>-default #1 SMP Wed Oct 11 18:58:12 UTC 2017 (4355936) x86_64 x86_64 x86_64 GNU/Linux
gcc (GCC) 4.9.3 20150626 (Cray Inc.)
(gdb) bt
#0  0x00002b54c8b0b875 in raise () from /lib64/libc.so.6
#1  0x00002b54c8005974 in monitor_signal_handler (sig=20, info=0x7ffd8c783730, context=0x7ffd8c783600) at ../../libmonitor/src/signal.c:246
#2  <signal handler called>
#3  0x00002b54c9965f74 in pfm_get_pmu_info (pmuid=1443482343, uinfo=0x7ffd8c783ae0) at pfmlib_common.c:1904
#4  0x00002b54c9d0d675 in get_first_event_next_pmu (pmu_idx=1443482343, pmu_idx@entry=-1, pmu_type=5) at components/perf_event/pe_libpfm4_events.c:448
#5  0x00002b54c9d0e5bf in _pe_libpfm4_ntv_enum_events (PapiEventCode=0x7ffd8c785c3c, modifier=<optimized out>, cidx=0, event_table=0x2b54ca075220 <perf_native_event_table>)
    at components/perf_event/pe_libpfm4_events.c:766
#6  0x00002b54c9cf6032 in PAPI_enum_cmp_event (EventCode=0x7ffd8c785c9c, modifier=1, cidx=0) at papi.c:1411
#7  0x00002b54c7dbd755 in display_events (self=0x2b54c7ff2280 <_papi_obj>) at ../../../../src/tool/hpcrun/sample-sources/papi-c.c:773
#8  0x00002b54c7dac1eb in hpcrun_display_avail_events () at ../../../../src/tool/hpcrun/sample_sources_registered.c:111
#9  0x00002b54c7da7504 in hpcrun_sample_sources_from_eventlist (evl=0x7ffd8c78e8cc "LIST") at ../../../../src/tool/hpcrun/sample_sources_all.c:242
#10 0x00002b54c7da1f69 in monitor_init_process (argc=0x2b54c821c2e8 <monitor_argc>, argv=0x7ffd8c788158, data=0x0) at ../../../../src/tool/hpcrun/main.c:817
#11 0x00002b54c800c470 in monitor_begin_process_fcn (user_data=0x0, is_fork=<optimized out>) at ../../libmonitor/src/main.c:262
#12 0x00002b54c800c813 in monitor_main (argc=1, argv=0x7ffd8c788158, envp=0x7ffd8c788168) at ../../libmonitor/src/main.c:488
#13 0x00002b54c8af7c36 in __libc_start_main () from /lib64/libc.so.6
#14 0x00002b54c800bebe in __libc_start_main (main=<optimized out>, argc=1, argv=0x7ffd8c788158, init=0x411ec0, fini=0x411eb0, rtld_fini=0x2b54c7b796f0 <_dl_fini>,
    stack_end=0x7ffd8c788148) at ../../libmonitor/src/main.c:539
#15 0x00000000004029e9 in ?? ()
#16 0x00007ffd8c788148 in ?? ()
#17 0x000000000000001c in ?? ()
#18 0x0000000000000001 in ?? ()
#19 0x00007ffd8c78a970 in ?? ()
#20 0x0000000000000000 in ?? ()

Deadlock starts on line 773 of papi-c (see frame #7)
769         printf("Name  Description\n");
770         printf("===========================================================================\n");
771
772         ev = 0 | PAPI_NATIVE_MASK;
773         ret = PAPI_enum_cmp_event(&ev, PAPI_ENUM_FIRST, cidx);
774         while (ret == PAPI_OK) {
775           memset(&info, 0, sizeof(info));
776           if (PAPI_get_event_info(ev, &info) == PAPI_OK) {
777             cmp_event_count++;
778             printf("%-48s\n", info.symbol);
779             print_desc(info.long_descr);
780             printf("---------------------------------------------------------------------------\n");
781           }
782           ret = PAPI_enum_cmp_event(&ev, PAPI_ENUM_EVENTS, cidx);
783         }

Inside PAPI's  _pe_libpfm4_ntv_enum_events (PapiEventCode=0x7ffd8c785c3c, modifier=, cidx=0, event_table=0x2b54ca075220 <perf_native_event_table>)
at  components/perf_event/pe_libpfm4_events.c:766 (frame #5)
761                     if ((ret = pfm_get_event_info(code, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
762                             SUBDBG("EXIT: pfm_get_event_info returned: %d\n", ret);
763                             return PAPI_ENOIMPL;
764                     }

Inside get_first_event_next_pmu (pmu_idx=1443482343, pmu_idx@entry=-1, pmu_type=5)
in components/perf_event/pe_libpfm4_events.c:448 (frame #4)
436       while(pmu_idx<PFM_PMU_MAX) {
437
438         /* clear the PMU structure (required by libpfm4) */
439         memset(&pinfo,0,sizeof(pfm_pmu_info_t));
440         pinfo.size = sizeof(pfm_pmu_info_t);
441         ret=pfm_get_pmu_info(pmu_idx, &pinfo);
442
443         if ((ret==PFM_SUCCESS) && pmu_is_present_and_right_type(&pinfo,pmu_type)) {

Within PAPI code in get_first_event_next_pmu (pmu_idx=-2057459418, pmu_idx@entry=-1, pmu_type=5) at components/perf_event/pe_libpfm4_events.c:505
pfm_get_pmu_info() returns PFM_ERR_NOINIT and never quits the while loop:
500       while(1) {
501
502         /* clear the PMU structure (required by libpfm4) */
503         memset(&pinfo,0,sizeof(pfm_pmu_info_t));
504         pinfo.size = sizeof(pfm_pmu_info_t);
505         ret=pfm_get_pmu_info(pmu_idx, &pinfo);
506
507             if (ret==PFM_ERR_INVAL) {
508                     break;
509             }
510
511         if ((ret==PFM_SUCCESS) && pmu_is_present_and_right_type(&pinfo,pmu_type)) {
512
513           pidx=pinfo.first_event;
514           SUBDBG("First event in pmu: %s is %#x\n", pinfo.name, pidx);
515
516           if (pidx<0) {
517             /* For some reason no events available */
518             /* despite the PMU being active.       */
519             /* This can happen, for example with ix86arch */
520             /* inside of VMware                           */
521           }
522           else {
523              SUBDBG("EXIT: pidx: %#x\n", pidx);
524              return pidx;
525           }
526         }
527
528         pmu_idx++;
529
530       }

I think that you’ve diagnosed the problem. Within the while loop, the PAPI code needs to be able to handle all of the error codes from  pfm_get_pmu_info. These error codes include
PFMLIB_ERR_NOINIT
    Library has not been initialized properly.

PFMLIB_ERR_NOTSUPP
    PMU model is not supported by the library.

PFMLIB_ERR_INVAL
    The pmu argument is invalid or info is NULL or size is not zero.

It should break on any of the three error codes. You can report that to the PAPI team.
The only outstanding question is whether we are initializing the PAPI library properly before this call is made. If so, then there is no further action for us in HPCToolkit.

I reported this problem to PAPI team 2 or 3 days ago.
Keep in mind that this problem only occurred on Titan. I have no problems
with all other machines I tested.
As you mentioned, the problem is inside PAPI. But this impacts us. Users
will complain to us, not to PAPI.
Btw, according Vince, this bug doesn't make any sense. But as you can see
with setenv/getenv problems, sometimes we encountered non-sensical issues.
Laksono Adhianto
On Thu, Feb 15, 2018 at 3:06 PM, John Mellor-Crummey <
<EMAIL_ADDRESS>wrote:

I think that you’ve diagnosed the problem. Within the while loop, the PAPI
code needs to be able to handle all of the error codes from
pfm_get_pmu_info. These error codes include
PFMLIB_ERR_NOINIT
Library has not been initialized properly.
PFMLIB_ERR_NOTSUPP
PMU model is not supported by the library.
PFMLIB_ERR_INVAL
The pmu argument is invalid or info is NULL or size is not zero.
It should break on any of the three error codes. You can report that to
the PAPI team.
The only outstanding question is whether we are initializing the PAPI
library properly before this call is made. If so, then there is no further
action for us in HPCToolkit.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/HPCToolkit/hpctoolkit/issues/52#issuecomment-366061618,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AIX86LQHcaTZo90flpLED03GmWujBBE0ks5tVJxZgaJpZM4SComj
.

I suspect this is the same mismatch of libpfm between PAPI and perfmon
in issue #51 and what I saw on theta.
The first thing to try is the --with-perfmon=PAPI workaround as
described in issue #51.  If that fixes the problem, then close this
one as a duplicate.

Fixed in commit f8702c7


Add guidelines for setting up the project with Truffle

This is just a recommendation. I'm not sure if that makes sense from a business standpoint but for contributors, it would be much easier if they knew how to setup truffle with the project.

truffle support please?


Unexpected indent on last line of snippet

The following snippet:
? tag
$ `{{` `}}`
<{{name}}{{}}>
	{{+}}
</{{~1}}>

Leaves the last line indented:
<foo disabled>
  text
  </foo>

I thought it might be autoindent, but turning that off didn't seem to affect it, and nothing seemed relevant in the formatoptions. Any ideas?

This is snippet for HTML, right? The default indentexpr for this filetype doesn't handle unknown/custom tag names very well

Ah, that makes sense


Does not load on WotLK build

The addon does not load on the WotLK pre-patch build. Is it possible that this could be updated to be compatible with the new patch?
This addon is a lifesaver and I hope it gets updated soon!
Thanks!

Hi, glad to hear that people are still finding a use for my AddOn!
I don't play anymore myself, so it's hard to test any fixes without a
subscription. I will try to do a basic update that I think might help, in
the next few days.
On Thu, 1 Sept 2022, 04:46 ajames27, @.***> wrote:

The addon does not load on the WotLK pre-patch build. Is it possible that
this could be updated to be compatible with the new patch?
This addon is a lifesaver and I hope it gets updated soon!
Thanks!
—
Reply to this email directly, view it on GitHub
https://github.com/haatveit88/finder-addon/issues/3, or unsubscribe
https://github.com/notifications/unsubscribe-auth/AEXJQRX4RLYZ26NEYEHXX2LV4AKKFANCNFSM6AAAAAAQB5R5WQ
.
You are receiving this because you are subscribed to this thread.Message
ID: @.***>

This has now been resolved and a new version is pushed to GitHub and Curse!


Run two concurrent worker processes

This updates the worker container to run a command that spawns two worker processes and then tails the logs, so we can see what's going on. I don't think specifying the delayed_job log file location will interfere with logit, but I'll keep an eye on it.

 Run two concurrent worker processes


git history extension works wrong

code-server version:  the latest docker image
OS Version: ubuntu 18.04
Extension: https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory

Description
When view some file's git history, it shows localhost deny.

Steps to Reproduce

open one file, click the git history icon

The gitHistory extension does not currently support remote editors.
see https://github.com/DonJayamanne/gitHistoryVSCode/issues/379
Many extensions of this nature expect localhost to be reachable by the interface. This won't work with the browser.
I suggest taking a look at DonJayamanne/gitHistoryVSCode and seeing if a patch to their repo would be accepted


Allow passing a venv to uv pip --python

Fixes https://github.com/astral-sh/uv/issues/3060
Summary
Allows passing a virtual environment (the path to the directory, rather than the path to the Python interpreter within the directory) to the --python option of the uv pip command.
Test Plan
Tested manually to confirm that the expected new functionality works. The test suite still passes after this change.
I don't know how to add tests for a new feature like this. I would be happy to do so if someone can give me some pointers on how to do it.

Will fix the failure, need https://github.com/astral-sh/uv/pull/3072 first.

Oh sorry, I set to auto-merge.

Not a problem. And thanks for (improving and) merging this - glad my beginner-level Rust was worth it!


Form Control Color width is too narrow

The Colorfield width is too narrow, making it impossible to enter values manually.

https://github.com/dengunorg/django-admin-kubi/blob/f755f16fded66cd60f9ca9ad714029f1c0a3a0aa/django_admin_kubi/assets/css/app.css#L2246

@pzandre added support for django-colorfield on v1.0.6


use rock in track/2.31

uses rock built from https://github.com/canonical/dex-auth-rocks/blob/track/2.31.2/dex/rockcraft.yaml
merge after #176
closes #173

Let's note also that from now on (https://github.com/canonical/bundle-kubeflow/issues/747), we will use - instead of _ before commit_id for publishing ROCKs.


Automated cherry pick of #3582: fix: 避免Openstack越过存储检查

Cherry pick of #3582 on release/2.11.
#3582: fix: 避免Openstack越过存储检查

Codecov Report

:exclamation: No coverage uploaded for pull request base (release/2.11@c68bec9). Click here to learn what that means.
The diff coverage is 0%.

@@              Coverage Diff               @@
##             release/2.11   #3585   +/-   ##
==============================================
  Coverage                ?   7.12%
==============================================
  Files                   ?     477
  Lines                   ?   77658
  Branches                ?       0
==============================================
  Hits                    ?    5536
  Misses                  ?   71654
  Partials                ?     468

Flag
Coverage Δ

#aFlag
7.12% <0%> (?)

Impacted Files
Coverage Δ

pkg/compute/models/guest_actions.go
0% <0%> (ø)

pkg/compute/guestdrivers/openstack.go
7.14% <0%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c68bec9...1f9a72a. Read the comment docs.

/approve
/lgtm


CPI job name is incompatible with multi-CPI

The job name is currently shadow-cpi in this Bosh release, whereas Bosh expects it to be shadow_cpi as per the multi-CPI docs: “Director will add _cpi suffix to the end of the type when calling the CPI binary”.

A possible workaround is to create a symbolic link for providing the shadow_cpi job as an alias of shadow-cpi with such YAML patch:
- path: /instance_groups/name=bosh/jobs/name=pre-start-script?
  type: replace
  value:
    name: pre-start-script
    release: os-conf
    properties:
      script: |
        #!/usr/bin/env bash
        set -ex
        cd /var/vcap/jobs
        ln -sfn shadow-cpi shadow_cpi

And this requires the os-conf release in the deployment manifest. It that may already be there, but can also be added with such YAML patch:
- path: /releases/name=os-conf?
  type: replace
  value:
    name: os-conf
    version: ((os_conf_version))
    url: https://bosh.io/d/github.com/cloudfoundry/os-conf-release?v=((os_conf_version))
    sha1: ((os_conf_sha1))

Sorry, wrong project


[BUG] lr scheduler get_last_lr() does work with fp16 enabled

Describe the bug
I am trying to get the current learning rate value during training for logging purposes using this function:
lr_scheduler.get_last_lr()
It works well when I am not using fp16 training, but when I enable fp16 I get this error:
Traceback (most recent call last):
...
aml_log_metrics({"training_loss":loss.item(), "learning_rate":lr_scheduler.get_last_lr()[0]}, distributed_args[0])
File "/azureml-envs/azureml_5c60934469eb9a6d2cc091063a233732/lib/python3.8/site-packages/deepspeed/runtime/lr_schedules.py", line 766, in get_last_lr
assert getattr(self, '_last_lr', None) is not None, "need to call step() first"
AssertionError: need to call step() first
i am calling step() before get_last_lr(), and it works when disabling fp16 training.
To Reproduce
Steps to reproduce the behavior:
I am using this type of loop, with fp16 enabled:
model_engine, optimizer, trainloader, lr_scheduler = deepspeed.initialize(...)
for epoch in range(config['epochs']):
for step, data in enumerate(loop):
logits = model_engine(...)
loss = compute_loss(...)
model_engine.backward(loss)
model_engine.step()
print("learning_rate" + str(lr_scheduler.get_last_lr()[0]))
Expected behavior
get_last_lr() should work with or without fp16
System info (please complete the following information):

OS: Ubuntu 18.04
GPU count and types: two machines with x8 A100s each
Python version: 3.8
Any other relevant info about your setup
openmpi4.1.0
cuda11.1
cudnn8
torch1.9

Launcher context
Launching experiment with azure MPI
Docker context
mcr.microsoft.com/azureml/openmpi4.1.0-cuda11.1-cudnn8-ubuntu18.04
** Deepspeed config file **
distillation_deepspeed_config_fp16.txt

@mbetser, thanks for reporting this error. Can you please share a simple script and steps to reproduce this issue?

@tjruwase
I have the same issue when I used this repo to train the model. The only change is set the precision to FP16

Hi @mbetser I was unable to repro the issue occurring only for fp16 I ran into the error regardless of data type. The solution is to either pass in an lr scheduler during initialization or through the ds_config as shown here.
Closing because it's such an old issue.


I can get the Plugin to connect to the Home Assistant.

Hi, I have been using the Streamdeck Home Assistant plugin for some time, and it has been working well. I am using the SSL connection (wss://< my url >/api/websocket) I had to rebuild my PC and forgot to backup the settings on the StreamDeck, and now I can't get it to work. I have created a new Long Live token, and if I use Postmen, it all connects fine using the same settings as I am using with the StreamDeck; however, in the Plugin, I get the following error.
Failed to connect to wss://< my url >/api/websocket
Im not sure how to get logs, etc. out of the stream deck, but I need this fixed because I use it all the time. im using
Home Assistant 2023.10.0
Supervisor 2023.10.0
Operating System 10.5
Frontend 20231002.0 - latest
StreamDeck <IP_ADDRESS>48

Added the port to your IP?

That may help. If yo do not specify the port, the defaults are port 443 for "wss://...." and port 80 for "ws://....". For different ports, you have to specify them after the domain "wss://foo.bar.com:8443/api/websocket".
Besides that: If you are using wss, please make sure, you are using a valid certificate. Self signed certificates are (and can not) be supported.

I have the same issue and it is most likely related to my certificates, however I am curious why this is an issue? If I use Postman I can connect to the Websocket API without any issues.

StreamDeck uses a kind of "internal webbrower" that runs the plugin. This brower does not accept self-signed or invalid certificates. From within my plugin i can not override this behaviour. :/
There are only two options

URL without TLS certificate
URL with valid TLS certificate

I think postman is less strict when it comes to TLS valdidation.

Having the same issue after a recente windows format, can't connect anymore

I will check with a totally fresh install of StreamDeck.

Hmm, i completely removed StreamDeck and deleted all related registry keys. After reinstalling StreamDeck, downloading the plugin and entering valid URL and Token, it works as expected. :/

Hmm, i completely removed StreamDeck and deleted all related registry keys. After reinstalling StreamDeck, downloading the plugin and entering valid URL and Token, it works as expected. :/

I tried but streamdeck seemed to remember the url i inserted in HA, which folders did you delete?

The plugin (or plugins in general) can store 2 different types of settings.

Global Settings (like URL and Token of my plugin)

Are stored in the registry (on windows) under
Path: HKEY_CURRENT_USER\Software\Elgato Systems GmbH\StreamDeck
Key: de.perdoctus.streamdeck.homeassistantde.perdoctus.streamdeck.homeassistant (can be deleted to "reset" URL and Token)

Button specific Settings

Are stored in the filesystem
Path: C:\Users\[your user]\AppData\Roaming\Elgato\StreamDeck\ProfilesV2 (warning, contains all your buttons. only delete if you want to re-config your whole streamdeck)

I closed the streamdeck app and deleted the whole streamdeck folder and the registry key. To reset only server settings, deleting the single key should be enough.

The plugin (or plugins in general) can store 2 different types of settings.
* Global Settings (like URL and Token of my plugin)

  * Are stored in the registry (on windows) under
    Path: `HKEY_CURRENT_USER\Software\Elgato Systems GmbH\StreamDeck`
    Key: `de.perdoctus.streamdeck.homeassistantde.perdoctus.streamdeck.homeassistant` (can be deleted to "reset" URL and Token)

* Button specific Settings

  * Are stored in the filesystem
    Path: `C:\Users\[your user]\AppData\Roaming\Elgato\StreamDeck\ProfilesV2` (warning, contains all your buttons. only delete if you want to re-config your whole streamdeck)

I closed the streamdeck app and deleted the whole streamdeck folder and the registry key. To reset only server settings, deleting the single registry-key should be enough.

Deleting the registry key seems to have worked, thanks!

how to conect to google home devices ?


Added spring-mvc unit test

Can one of the admins verify this patch?

ok to test.

test this please.

fixes #60

How is #60 fixed by this?

This code creates a unit test for BaseController and mocks kilkariService
so it throws an exception.  It then verifies that the exception was thrown
and that the status is Internal Server error.
Are you expecting it to do something different?
On Mon, Apr 27, 2015 at 8:35 AM, Frank Huster<EMAIL_ADDRESS>wrote:

How is #60 https://github.com/motech-implementations/mim/issues/60
fixed by this?
—
Reply to this email directly or view it on GitHub
https://github.com/motech-implementations/mim/pull/188#issuecomment-96712896
.

Ah, cool!!!
I thought you were using kammad as a test for fake checkins.
I didn't really look at the actual changes, my bad.


Bug title

Which version of the app?
WinUI 3 Gallery
Description
No response
Screenshots
No response
Windows version
No response
Additional context
No response

Blank Issue


Solution for 8-way map on sticks and DPad

As of right now, the Split element allows a negative and a positive input for each axis, so 4-way is fully achievable with it. 4-way is inherently available on the per-direction DPad mapping.
Anyway, I've skimmed over the documentation, and I cannot figure a way to achieve maps-per-diagonal as well, and this makes sense. A diagonal simultaneously exists on both axes/buttons, and Xidi is configured per-axis/button.
Sonic Heroes could use this- it has a first-person freelook cam that is mapped to eight Numpad directions. I don't think this would be very feasible with the existing defined axes in a logical manner. New merged axis definitions would likely need to be added (StickLeftXY, StickRightXY), with an extended eight-value element ("8Way"?) valid only to it that defines each of the eight discrete directions. You couldn't use these alongside the original axis equivalents, and it'd probably have priority in-case someone had an errant Xidi.ini containing both.
StickLeftXY	= 8Way( [Up], [Down], [Left], [Right], [UpRight], [DownLeft], [DownRight], [UpLeft]  )
StickRightXY	= 4Way( [Up], [Down], [Left], [Right] )

This is just a brainstorm. It's a little messy like this- I'm having difficulty figuring out the most reasonable way to achieve this. Also above is my idea for a shorthand version of implementing 4-way versus the current way of achieving it.
DpadUp		= Keyboard(Numpad8)
DpadDown	= Keyboard(Numpad2)
DpadLeft	= Keyboard(Numpad4)
DpadRight	= Keyboard(Numpad6)
DpadUpRight	= Keyboard(Numpad9)
DpadDownLeft	= Keyboard(Numpad1)
DpadDownRight	= Keyboard(Numpad3)
DpadUpLeft	= Keyboard(Numpad7)

Since DPad is already split to four discrete directions, four more could simply be added- using the current 4-way behavior unless the 8-way values exist and are defined.
I apologize for the length.

Is there something in particular you are trying to achieve that the game doesn't already support?
DpadUp		= Keyboard(Numpad8)
DpadDown	= Keyboard(Numpad2)
DpadLeft	= Keyboard(Numpad4)
DpadRight	= Keyboard(Numpad6)

Just these four lines are enough to get the in-game camera working properly with diagonals; pressing two dpad directions at once makes the camera move diagonally.
Also, this game supports free camera motion via analog axes, which is mapped to the right analog stick in this configuration file.

Okay, yeah, that makes sense. I'm so used to just dealing with games' problems with hardcoded axes that I just assumed Sonic Heroes doesn't support freecam control on stick due to dev oversight or something. I had assumed that the profile there just didn't take that into consideration since it's a pretty unimportant feature, and the devil's in the details when StandardGamepad alone fixes it.
I'd say this issue's pretty null now, so I'm going to close it. Almost all 8-way movement can be interpolated across 4 keys or buttons, and I can't imagine too many things would need this level of configuration, if anything at all. It's even likely that Sonic Heroes interpolates 2/4/6/8 to diagonals when holding adjacents- and even if it doesn't, it has native analog stick support as mentioned. Thank you for your clarification!


[2.5] Allow local cluster to deploy monitoring

Backports https://github.com/rancher/rancher/pull/30540
(cherry picked from commit e851baaee049f9851193e5baa649cd4db9ef273d)

issue: https://github.com/rancher/rancher/issues/30537


fix: pass 0 instead of nil for current buffer

Ref https://github.com/neovim/neovim/pull/16745
Fix #226

@folke this is a pretty serious breaking change (affecting many plugins, even); mind giving this a look?

Thanks! Sorry I didnt check this sooner. Was traveling.

Thanks! Sorry I didnt check this sooner. Was traveling.

No apologies needed. Much thanks for all you do in the OSS community!


Move sound API into Flutter

Move the sound API into Flutter (it's currently in sprites).
API is currently here: https://github.com/vlidholt/sky_engine/blob/master/skysprites/lib/src/sound.dart

After a recent discussion, we've decided to make an effort to move more functionality into dedicated packages. Here's the request to create a new flutter_audio package: https://github.com/flutter/flutter/issues/1364
Going to close this one. Please reopen if we're talking about two different things.


Give explanation of errors on "Blockly -> Marlowe conversion"

See feedback:
Most important: when I pressed the button "-> Blockly to Code" nothing happened! The result was that I lost all my work!

Idea suggested:
One thought is to add a “hole” to the Haskell in the case of a hole in the Blockly?


Few Changes to Header

I'm Working on the Header.
Ill be Changing the Unwanted Search btn and Dark mode Btn

/assign


Date format in histograms

Change date formats in time-series widgets.
Coming from https://github.com/CartoDB/design/issues/925
Change formats to:

Minutes: 12:34 - Jan 21st, 2015
Hours: 12:34 - Jan 21st, 2015
Days: Jan 21st, 2015
Weeks: Jan 5th, 2015 (first day of week)
Months: Jan 2015
Quarters: Q1 2015
Years: 2015

In production


Getting blank sheet

Hello all, I am using excelize for a long time, and I have noticed that I am getting blank sheet (blank file).
It is happening on all OS platforms.
Issue happens randomly, if i start same export of data once it can be filled, once I get empty sheet.
It can happen that I have blank once in 1000 or so.
After hard testing I have spotted that part which is causing this issue is in f.DeleteSheet("Sheet1")
I am calling this function before I use SaveAs. Before that I have tracked data, and xlsx file should be populated, but excelize saves empty file.

Hi @OFAH, thanks for your feedback, please provides test code, file attachment and environment information if you can.

Hi @xuri, I can not provide you my code because of ISO.
But I will try to create same test code as I use. I build go file on Ubuntu 16.04.5 LTS, and GO version is is: go1.10.4 linux/amd64.

This issue is solved now. I have pulled latest version, and it is all ok now.


[RFC] Relay Dynamic Runtime

Putting the VM in TVM: The Relay Virtual Machine
We have previously introduced Relay, a new program representation,  which is able to represent and optimize a greater breadth of machine  learning programs. Unfortunately by supporting a more expressive set of programs we  introduced several new execution challenges. So far we have not provided a  production-ready solution to executing full Relay programs, i.e those containing control-flow,  abstraction (both data and functional), as well as dynamism.
We introduced a “debug” interpreter which performs naive AST traversal  to execute the program. This approach is conceptually simple but requires  traversal of the program for each evaluation. The program is stored as a tree which makes heavy use of indirection and leads to inefficient execution.
There are still unknown dynamism issues such as dynamic scheduling and allocation, fully dynamic tensor shapes, and control-flow. The interpreter has simple solutions for these, but none provide a compelling and optimized solution.
The second execution mechanism is the existing graph runtime, in order to target Relay programs to this we translate a small subset of them to the
old graph format, and execute them on the runtime. This provides a solid execution
experience but only for a very limited subset of Relay programs.
Finally we have developed an experimental ahead-of-time compiler,
which transforms a Relay program into a shared library which implements it.
This final approach provides compelling performance but is hard to extend with new
approaches to handling dynamic programs.
This RFC proposes a new virtual machine for Relay programs. The virtual machine is designed to strike a balance between performance and flexibility when deploying and executing Relay programs, without giving up the benefits of TVM.
Virtual machine (VM) design is a well studied area in programming languages and systems,  and there have been various virtual machine designs for both full fledged,  and embedded programing languages. Previous language VM designs have been heavily tailored to the execution profile of traditional programs. Traditional programs manipulate small scalar values and consist of a large number of low level instructions. The sheer quantity of instructions to compute requires instruction execution and dispatch to be extremely efficient.
In the context of machine learning we manipulate primarily tensor values, using a (relatively)  low number of high level instructions. ML program's cost centers are expensive operator invocations  such as GEMM or convolution, over a large input. Due to execution profile exhibited by ML programs micro-optimizations present in scalar-VMs are dramatically less important. A model’s runtime will  be dominated by executing expensive operators on large inputs.
TVM has provided a strong support for vision models, but we want to grow to support a wider variety of models. The graph runtime is able to utilize the fully static nature of the input graphs to perform aggressive optimization such as fully static allocation, and optimal memory reuse. When we introduce models which make use of control-flow, recursion, dynamic shapes, dynamic allocation we must change how execution works.
The rest of this design document is focused on explaining a VM which addresses these challenges and and explores  design decisions which remain.
Proposed Design
I have been experimenting with different designs and discussing how
to solve this problem with members of the community for the past few months.
Our belief is the most important design aspects  will be optimizing for cheap “allocation” of
objects (by trying to avoid real allocation, reuse of static fragments, and the ability
to do dynamic (i.e jagged tensors).
Instruction Set
The critical design choice of a VM is the instruction set and their representation.
The current representation of the instructions is a tagged union, containing the op-code and the data payload.  An important design decision is the level of abstraction of the instructions, and how they take their data, that is RISC vs. CISC and fixed-width instruction encoding vs. variable length. The current version is closer to CISC with complex instructions like AllocTensor, and is variable length due to the inclusion of the shape as part of the instruction. The current instruction set is very high level and corresponds roughly to high level operations in Relay.
Push
Arguments:
size_t stack_index
Reads the value at base pointer + stack_index and pushes
it on to the stack.
Pop
Arguments:
size_t pop_count
Pops pop_count number of entries off the stack starting from the end.
Ret
Arguments:
None
Returns from the current function call, popping off the last value of
the frame stack and restoring the VM state that was recorded at the
last call site. The last value on the stack is interpreted as the
return value.
InvokePacked
Arguments:
size_t packed_index
size_t arity
size_t output_size
Invoke the packed function denoted by packed_index. The arity
and output size are used to inform the VM how many inputs and
outputs to expect.
AllocTensor
Arguments:
const std::vector<int64_t>& shape, DLDataType dtype);
Allocate a tensor value of the appropriate shape and dtype.
AllocDatatype
Arguments:
(size_t tag, size_t num_fields);
Allocate a data type with the tag tag using the
top num_fields entries on the stack as its fields.
AllocClosure
Arguments:

size_t func_index
size_t num_freevar

Allocate a closure with the VMFunction at func_index as
its code, and the num_freevar entries on the stack
as its free variables.
GetField
Arguments:

size_t object_offset
size_t field_index

If
Arguments:

size_t true_branch
size_t false_branch

Check if the top element on the stack is true or false.
If true relative jump by true_branch, else relative
jump by false_branch.
Goto
Arguments:

size_t pc_offset

Relative unconditional jump by pc_offset.
Invoke
Arguments:

size_t func_index

Invoke function at func_index, consumes the number of arguments contained in the VMFunction's
arity field, and places return value on stack as top element.
InvokeClosure
Arguments:
None
Expects the top value on the stack is a closure. Invokes closure consuming the number of
arguments declared in the closure_index's VMFunction, and places return value on the stack.
LoadConst
Arguments:

size_t const_index

Load the constant at const_index from the constant pool.
Object Representation
We use a simple object representation that uses shared pointers and tagging.
There is a huge space of object representations we can trade off here, but we
believe micro-optimizing this code has little to no-effect on the end-to-end performance.
struct VMObjectCell {
  VMObjectTag tag;
  ...
};

struct VMObject {
  std::shared_ptr<VMObjectCell> ptr;
  ...
}

See vm.h for more details.
Currently we support 3 types of objects, tensors, data types, and closures.
VMObject VMTensor(const tvm::runtime::NDArray& data);
VMObject VMDatatype(size_t tag, const std::vector<VMObject>& fields);
VMObject VMClosure(size_t func_index, std::vector<VMObject> free_vars);

Stack and State
The Relay VM consists of two important stacks, the value stack which acts as the normal call stack
as used in C/C++/Java/etc, and the frame stack, which contains information about how to resume the
previous call.
A stack machine is straightforward to implement, register-based virtual machines are more efficient
in the scalar-world, but we believe in the tensor world that the complexity to performance gain
tradeoff is not worth it.
We keep track of a set of Relay functions we have called, a pointer into its bytecode, a offset into the byte code known as the program counter, as well as an offset into the value stack which tells us where the stack frame begins known as the base pointer.
struct VirtualMachine {
    ...
    std::vector<VMFrame> frames;
    std::vector<VMObject> stack;
    ...
    // Current function.
    size_t func_index;
    // Pointer into the current function's instructions.
    const Instruction* code;
    // Current program counter relative to the code pointer.
    size_t pc;
    // The current base pointer.
    size_t bp;
    ...
};

Dispatch Loop
A very critical piece of a VM is the dispatch loop, usually this dominates execution time of a virtual machine, but experimentally we have found the performance of the loop to not be of much importance. We have just implemented a simple switch/goto dispatch loop which dispatches based on instruction op code.
This loop is implemented by VirtualMachine::Run().
It is my belief that this code is not as important to end-to-end performance as allocation,
and memory reuse.
VM Compiler
An important part of this infrastructure is a compiler from Relay's full IR into a sequence of bytecode.
The VM compiler transforms a tvm::relay::Module into a tvm::relay::vm::VirtualMachine. The virtual
machine contains a set of compiled functions, the compiled functions are contained in tvm::relay::vm::Function. The functions contain metadata about the the function as well as its compiled bytecode. For full definition of the data structures see vm.h.
Optimizations
There are quite a few optimizations required by the VM compiler.
We have implemented them in the old pass style, but plan to port them to
the new pass manager (#2546) before merging.

A-Normal Form
Lambda Lift (see src/relay/vm/lambda_lift.cc)
Inline Primitives (see src/relay/vm/inline_primitives.cc)
Inliner (see src/relay/pass/inliner.cc)
Tail Call Optimization (see ...)
Constant Pool Layout (see ...)
ADT Tag Allocation (see ...)
Liveness Analysis (see ...)

Serialization
A final and yet to be implemented part of the VM design is serialization. This accompanying PR will introduce both the bytecode, its serialization, as well as VM level serialization. The idea being that a VM can be efficiently stored to disk and resumed at a later time. This would also allow us to efficiently schedule many models on to a single machine in order to obtain good utilization.
Unresolved Questions
How do we handle dynamic shapes?
I have another prototype extension to Relay which adds initial support for compiling and executing programs containing fully dynamic shapes. I will post an RFC and prototype PR on this subject soon.
How can we modify the VM to support JIT compilation of certain code paths?
In the code generation space there are still many tradeoffs to be analyzed and the VM is designed
to be very flexible so we can modify it for future experiments.
How do we support heterogenous execution?
Heterogenous execution should work out of the box assuming we have annotated the appropriate device copies.
In order to do this properly we need to run the device annotation and copying passes. We for see nothing too complex in this work.

cc @tqchen @icemelon9 @wweic @zhiics @MarisaKirisame @junrushao1994 @abergeron @ajtulloch @antinucleon

I am not a big fan of stack machines because it creates a self-inflicted serialization constraint on the operands.  I would rather see a large register abstraction for tensor operands, so that concurrent execution is readily analyzable as read/write hazards and reordering are directly visible to the scheduler.
Stack machines are unpleasant to do in hardware, and history shows you that all hw engines for stack machines first unpack the stack and cast them back into a register-based resource structures before they start executing.
My vote is against a stack-based VM.

@Ravenwater What else do you propose if you don’t like stack-based VM?

Good discussions so far.  I think we want to de-couple the RFC into two components:

(1) Runtime data structure and related instructions

Data structures set and primitive instruction (like Alloca) set a foundation for most of the implementations details, many of those are independent of the VM's implementation.

(2) Implementation: stack vm / register based vm / directly compile into AOT(LLVM)

Most of the implementation will likely depend on the data structures and the control flow execution part can be relatively independent of implementation.

(3) Scheduling

Scheduling layer, by itself, can again be somewhat independent of stack/register based implementation. If every invocation of the code can be again dispatched by an independent task scheduler dynamically as those in common deep learning frameworks.

I would recommend we focus on discussing and agreeing on item (1) since this is the most important thing in the short term. Having a stack-vm as a starting point is fine due to its simplicity as long as we have some good thoughts on scheduling.

@tqchen It's not trivial to separate instruction to stack-unrelated and stack-related because it affects the calling convention. For example, invoke instruction assumes all the input tensors and return tensors are already pushed on the stack.
But I agree that we should have a debate on whether to go with stack vm vs register vm first.

@jroesch @junrushao1994 To clarify the statement: don't use a stack to manage operands to work on. The stack manipulations to order operands and results for the instruction set is the culprit: that creates a serialization that has nothing to do with the algorithm to be executed, but everything to do with the resource constraints of the stack operators and virtual instruction set. To extract concurrency, you need to 'unroll' all these stack operations to remove the artificial stack-machine created read/write hazards.

@icemelon9 my vote is to take the operand slots in the stack frame and map them to an abstract register file and operate on them with a register-based instruction set. This will make it easier to map the execution onto a traditional stored program machine with registers, direct execution pipelines, systolic arrays, and distributed data flow engines.

I meant that while the calling convention(whether arguments should be on stack) could differ in register vs stack-based vm.  Anyway, we can also see if we can get a concrete proposal of a more "register-based" version.

Interpretable-SSA-virtual-machine.pdf

At a glance, I think this approach will work very well. It's very similar to what is used in libraries like PyTorch JIT, which try to solve a very similar problem, e.g. https://github.com/pytorch/pytorch/blob/47bf30661fb45f106e2b609495d82af463513b99/torch/csrc/jit/interpreter.cpp#L700-L769, etc.

@Ravenwater I understand the difference between stack vs register based VM. But could you please be more specific about scheduling and parallelism in this context? I might miss something here. IMO, I think the most parallelism we could get should be from they way that we invoke the packed primitive functions, but that is oaky for the current design.

@zhiics A stack-based ISA defines the operands of its instructions relative to the position of top of stack. This simplifies the ISA because you don't have the addressing space/assignment of a register file. However, you also lose the ability to exploit concurrency between operators, as they are all serialize through the top two three positions of the stack.
When you think of many computational graphs they tend to be trees of 'stuff', where the leave operands are independent. All that represents opportunities for the hardware to execute operators concurrently.
If you look at what a JVM JIT needs to do, it basically executes the stack program, extract the operands, assign them to registers and issue the associated instruction. To extract any concurrency, the JIT needs to unroll the stack instructions, which are a serialization constraint created purely by the VM: they are not present in the computational graph of the program.

@Ravenwater Do you mean the current design has difficulty of handling operator level parallel execution, which is important for networks such as RNN?

Some followup comments:
First of all, StackVM implementation do not necessarily ties into serial execution. Most of the deep learning framework has extra asynchronous scheduling engine, that executes these instructions asynchronously based on dependencies. This essentially a "unrolling" approach. In the case of traditional vm, because the operational unit is scalar, performing such kind of execution can cause performance regression. In the our case, such cost can be mitigated because each operation are tensor ops.
One important benefit of the stack vm is that it is simple to implement and extend, such simplicity could out-weights a lot of things.
Regardless of stack vs register based implementation, we always need to have a call stack for function calls, and because we need tail recursion optimizations in our case, perhaps stack vm's abstraction makes it relatively easy to do so.
Finally, since our high-level program is always relay, we do not have to perform all the optimizations like parallelization detection and distributed mapping at the level of the VM. Relay by itself is much closer to a computational graph form, and can be used for such high level analysis and transformation.

I think we need to be specific about what are the workloads we would like to schedule for Relay and design for that.  From my experience looking at the opcodes generated by the Proof-of-Concept Relay VM, the most heavy lifting opcode is InvokePacked, which invokes a packed function that does some extensive tensor computation on some device. Majority of the remaining opcodes are for control flows, object allocation and deallocation etc, which I don't think would benefit much from concurrent execution. What we really need is probably  to hook an async execution engine with InvokePacked as @tqchen mentioned.

To be clear, we do want to think about how concurrency can be handled in each type of implementation. Concurrent execution does not have to be implemented now but should be considered in design scaffolding.
My last comment seems to mainly favor stack VM, given that there is also some amount of interest in register-based VM implementation.  I would recommend that we also have an alternative design proposal for register based VM.
In particular, pytorch's JIT seems to use a resizable register that avoids spilling(which makes sense) and might also make things simpler to implement.  In our case, it would be very useful to discuss how can tail-calls being handled in each case(stack and register), and how memory allocation and de-allocation can be handled in each case.

I ever done one compiler translation from register-based to stack-based and also from stack-based to register-based too. They are differ in some ways, but I must to say,  according to my experience, I don't think it is the important factor we should care for this RFC. And for TVM, not everything is done in this VM (if I don't misunderstand) and we also have other schedule engine.
For me, this is generally good and I care one thing: how to handle memory allocation efficiently? For dynamic, if we allocate every time, we lost all advantages.
Another thing I care: How to we support other inference engine (like tensorrt / NPU framework) if we have VM? I know maybe it is somehow obey go against to TVM's design.
Ever, we could do like this:
                     FE
                     |
              NNVM / Relay
               |       |
       NNVM graph   NPU-supported op graph
                  |
                 TVM  ---->   TVM Runtime (+ libTensorRT | libNPUInferEngine)

How could we handle this situation after we have VM? Many NPU Infer Engine / Tensort only expose high-level interface (like framework's API inference, addConvolution, addRelu, createInfereEngine and so on).

For (parallel) hardware accelerators, and in particular, parallel tensor processors, the hardware will have to do most of the scheduling. Memory allocation constraints are mostly for sequential stored program machines. For distributed data flow and PIM architectures the allocation must occur during execution typically just-in-time underneath the execution wavefront as it emerges in the machine.
In the Mathematics of Arrays, this resource allocation is provable optimal, and like any scheduling algorithm, the more information you have about the graph the better job you can do. Looking at the trend forward, the scheduler will disappear completely in the hardware as that is where the queuing and resource constraints are known.
It is with this simple observation that stack-based ISAs are unpleasant as the information the hw scheduler can see, is minimal.  It will need to execute the actual program to get to a representation that can feed into an optimizing scheduler for tensor compositions.
The ultimate NPU will control and manage the stack frames as well, so it can take advantage of cross function call boundary concurrency. The reason that this becomes essential for parallel hardware is that when the concurrency grows filling and draining the pipeline (think 1M+ ALUs) becomes a major limit on the execution efficiency of the machine. The hw scheduler needs to have all the information to avoid draining the execution resources.
A lot of the discussion appears to be governed by how to schedule for a sequential machine. But DL is one of those applications where the sequential machine is irrelevant as the computational demands require extreme concurrency. I totally agree with @wweic that organizing this discussion by the demands for specific models is going to be a worthwhile experiment.

Though most of parallelism happens in the packed function, it is still possible to execute two packed functions in parallel especially for inference in the cloud. However, to some extent, stack-based vm enforces certain orders when performing stack instructions. It potentially makes it harder to design an async executor.
One important goal for vm design and hardware-independent instructions is to provide more flexibility to write different executors given different requirements. My feeling is that converting from a register vm to a stack vm is easier than vice versa. @FrozenGene you can chime in since you've done both.
In terms of optimization, such as tail recursion, memory allocation, live analysis mentioned by @tqchen, it could be othorgonal to whether it's a register vm or stack vm. I believe you can write optimization passes for both.

@icemelon9 and to continue speaking in generalities to create simple dichotomies, recursion is bad for building parallel hardware execution engines, again due to the sequentialization semantics of the recursion.
For good scheduling of tensor compositions, you want the whole composition expression so that all the expansions (Kronecker products etc.) and contractions (dot, matvec, matmul) are visible.

My personal opinion is we need to abandon modeling VMs as high-level versions of an ISA, and its implementation as micro-architecture. We are in a fundamentally different world for executing Relay programs. The VM is only the control plane, the data plane is the the computation contained in highly optimized kernels produced by TVM.
We no longer compute over scalars the lessons learned from building scalar VMs and ISAs don't really apply.
The program of question is a high level data-flow program where an order has been selected. One simple version of this ISA is one where each computation instead places a future on the stack, which will eventually be completed by executing the packed function in parallel.
An implementation of this kind enables asynchronous and out of order execution while being completely opaque to the VM's compiler and end-users. If we want to enable higher level forms of speculation and parallelism we can borrow ideas from parallel functional languages to change the program before scheduling on the VM (see https://simonmar.github.io/bib/papers/monad-par.pdf).
Simon has quite a few different designs in place and has used some of them to build a highly concurrent system now deployed at Facebook, the core of the library is here (https://github.com/facebook/Haxl).
On the topic of recursion, iteration and recursion are isomorphic. There is no fundamental difference, any tail-recursive function can be converted to a loop and vice-versa. In this case we perform tail-call optimization which removes the recursive call leaving only a goto instruction.
If we wanted to perform instruction level scheduling this would be no worse than the code generated by a loop, but maintains the high level properties enjoyed by Relay today.
The only thing that may be more challenging is speculative execution, but speculative execution at the instruction level isn't particularly interesting in my opinion. The only meaningful speculation is at control boundaries such as loops or conditions such as TensorFlow does (https://www.tensorflow.org/api_docs/python/tf/while_loop, see parallel iterations).
If we want to provide non-strict semantics we should just transform the source program and use a simple mechanism like the one exposed in the Par paper described above.
A final argument is that the current graph-runtime is effectively a stack, with each node having pointers into it, the only difference is it can not grow and/or shrink.
The most important concern in my opinion is memory optimization. The current prototype has a new allocator API which we intend to leverage. We can perform dynamic allocation with a specialized allocation cache which will avoid repeatedly allocating memory from the system allocator.
The next step is to perform an optimization where we group allocations into blocks, and then request a dynamic block of the correct size. In this case code like loops which release, and re-request an identical size block each iteration will end up reusing the same block.
A final optimization is applying a static analysis like the current memory planner where we recover static allocation sizes, note that we can no longer do this in all cases due to dynamic behavior (loops) and when we introduce dynamic tensors the shapes will not be known until runtime.

@jroesch that is a good argument, and I can get behind that. I think I can see a path from the proposed VM structure to our domain flow world. (Domain flow is distributed data flow)
I do want to point out that in a distributed data flow environment there are no goto's as there isn't a globally addressable resource. Similarly, memory allocation transforms to resource reservation guarantees that occur throughout a distributed machine and become implicit during execution. To implement recursion in a domain flow architecture requires complete unrolling of the program graph and mapping it on a physical network. So, recursion on a random access machine may be cute, on a domain flow machine it is still an open research problem. We'll have to punt on any recursive algorithms, or depend on a rewrite.

I think it is important to remember this doesn't have to be the only way to execute Relay programs.
Users are free to design and implement others. It is hard to build a single abstraction that maps well to all possible hardware platforms.
Relay is still relatively high level and can be transformed into an IR subset free of a device's particular challenges, i.e by performing loop unrolling (which is also possible with recursion).
A key design goal here is to provide a generic VM that satisfies common general purpose devices (i.e x86, ARM, GPU), and integrates with a class of accelerator designs. For example TPU-like devices can easily be integrated into this design as packed functions which offload a subset of the network to the device.
There are classes of models which are fundamentally recursive, and will not map to hardware devices which can not support dynamic, unbounded iteration/recursion. Many accelerators will never support executing entire models of this class, and heterogenous execution is required.
A goal of Relay is to optimize and execute arbitrary models without restricting the program representation or runtime system by the semantics of the minimally expressive device. Devices with limited semantics will be unable to execute some programs and there is no way around that.
Though if you architecture can map dataflow style token passing to your device, i.e TensorFlow loops, then by definition you can execute a large set of recursive programs just by performing a program transform. This transformation is the inverse of the recent TF loop decompilation, and is the easier way to perform such transformation.

@jroesch I agree with your argument that the VM design should be generic and allow different ways to implement an executor. But I have a different perspective on stack VM vs register VM. I think register VM is more general than stack VM in this sense.
For example, as @Ravenwater mentioned, it's easier to implement a dataflow executor from a register VM since registers naturally reveal the data dependency. In comparison, you need more analysis to track such dependency from a stack VM. I quickly scan the monad par paper, and feels that it's an overkill and adds more complexity to VM's compiler. Using future and callback might cause more overhead imho.
Now compare the complexity of register VM and stack VM. I think they're similar. Both VM designs need optimization passes like tail recursion, live-cycle analysis, memory planning. We can also have AllocTensor instructions in the register VM such that we can use memory manager to make the memory sharing opaque to VM's compiler. And we don't need to worry about register spilling if we support resizable register file.

@jroesch Domain Flow is not Data Flow. Data Flow has no concept of space and time, just dependencies. Domain flow has a relative concept of space and time. Mapping onto a Domain Flow Architecture is akin to place-and-route, although computational graphs tend to be simpler and more structured than circuit graphs. The relationship between these two models of computation is that if you expand the computational graph to the bit-level operators you end up with a circuit graph, on which synthesis operations such as retiming and path length alignments are possible.
For tensor math and in particular tensor compositions, we want to take advantage of the structure of the tensors and tensor operators, so we will stop well short of the circuit graph and synthesize a Domain Flow program instead. But true gate synthesizers may not want to stop there and they may want to generate the full bit-level operator graph and the associated circuit graph to place-and-route on future 100BGate FPGAs. Recursion is a Random Access Memory concept that only understands sequence dependencies, and thus will never be a good abstraction for parallel hardware.

@Ravenwater I am fine with both stack VM or register vm, but sorry I am not an expert in FPGA stuff, and could not understand many of your concerns. Particularly, I have several questions.
First, what on earth is domain flow, could you define it in a more formal language? What do you mean by "a relative concept of space and time"?
Second, about your concern about recursion. From my point of view, recursion is about expressiveness, as modern neural networks (and differentiable programming) requires Turing-completeness. Sacrificing expressiveness is to sacrifice all future opportunities for deep learning models. Is there any alternatives that are developer-friendly, PL-correct and Turing-complete without recursion?

@junrushao1994
Here is the academic research background:
Domain Flow and Streaming Architectures: https://ieeexplore.ieee.org/document/145479
Domain Flow Architectures are basically direct execution structures for systems of affine recurrence equations after the seminal work by Karp, Miller, and Winograd on the characterization of concurrency of parallel algorithms based on uniform and affine dependencies.
The Organization of Computations for Uniform Recurrence Equations: https://dl.acm.org/citation.cfm?id=321418
That is the basic research that has lead to the Polyhedral compilation framework which provides the mathematics behind Halide and Tiramisu (https://www.csail.mit.edu/research/tiramisu-compiler)

@junrushao1994 There is also a new strain of tensor composition scheduling that is based on the Mathematics of Arrays (MoA) from Lenore Mullen
https://arxiv.org/abs/0907.0796
Tensors and n-d Arrays:A Mathematics of Arrays (MoA), psi-Calculus and the Composition of Tensor and Array Operations

The implementation of the hardware is not of interest to the high-level Relay program all Tensor to Tensor functions are black box. They can be implemented anyway you want, in C++, in TVM, or as a hardware accelerator primitive. If you want to map a subset of the program down to this hardware you will have to unroll it, which is required by most fixed-function hardware. You can then replace the unrolled program as a new operation and rewrite the program to use this instead.
Hardware that does not support arbitrary & dynamic program sizes can not execute all models of interest, they fundamentally don't fit into Halide/TVM style DSLs. The deep learning community has focused on optimizing for  small subset of models with very regular behavior, but the next wave of models invalidates many assumptions, such as statically known dimensions or static control-flow required by polyhedral optimizers. The point of this VM is to coordinate at the higher level where you need iteration, dynamic allocation, and communication.
I have thought further about a register based VM and see no strong argument for why registers are better than stacks. Most of the research on dynamic VMs focus on this distinction in order to reduce memory movement and dispatch overhead while executing the application. Packed functions will dominate execution time and optimizing for dispatch is an incredibly premature optimization.
The other argument for register based VMs is instruction level parallelism. Again instructions don't matter much here, meaningful parallelism is happening at data dependencies between operators, and inside the operators themselves (i.e parallel matrix mul).
The point of the parallel monad approach is not to add it to the source language, but that the execution technique is valid way for us to get parallelism between operator invocations. We can view the future graph as the data dependency graph and do graph reduction over it.
For example if I depend on a sequence of function calls it is valid to evaluate them in parallel while evaluating a future computation that may depend on its result. The amount of synchronization needed here is very small, and again the real opportunity for parallelism is inside operators in the tensor to tensor functions. We don't need to worry about where the results are stored, we essentially give it a register name when we push a future into stack position n.
In a sense we already have an infinite register because we can address any stack position. In this case we can easily address a future result by referencing position n.  The only difference is the location where operations look for their result. We need a call stack for functions, and function calls are the primary operation based on observations of current workloads.
Furthermore the current approach makes the VMCompiler far simpler, and easier to extend.
I personally value simplicity, we have zero evidence that the current approach is slow, in fact we have evidence of the contrary. The initial prototype is already faster than MxNet's executor which is used in production at AWS.

I posted a draft PR of the VM so everyone can check it out, provide feedback, and play with the prototype I discussed. See #2889. I'll be polishing it over the next few days.

@jroesch your argument is better than my argument, and I certainly subscribe to the power of simplicity. Hence, I will adapt and learn from your stack-based VM. Thank you for the thoughtful articulation of the pros and cons, and recording it in the development stream. This is excellent work.

close for now as we converge in VM deisgn


Added documentation on how to disable Kernel Lockdown

See #201

Just a heads up, over here the path is /sys/kernel/security/lsm.

Linux 5.6.0-2-amd64 #1 SMP Debian 5.6.14-1 (2020-05-23) x86_64 GNU/Linux3
Debian GNU/Linux bullseye/sid

Right, must have misremembered. I've corrected it.


Revert "[flutter_conductor] Auto apply dart revision"

Reverts flutter/flutter#82601.
Failed analysis post-submit.

Reverting TBR by @jonahwilliams to fix the tree.

LGTM


No issues found with component header that contains html markup

I noticed that if a have a cfscript component header with html markup in it that CFlint will not report any issues.
/**
 *
 * Some hint
 *
 *
Usage:

 *
Code example here

 *
 *
 */
component {

Output:
Total files:1
Total lines:57

Issue counts:0

Total issues:0

However if I remove the html markup.
/**
 *
 * Some hint
 *
 */
component {

Then I get the reported issues I expect to see.
Total files:1
Total lines:44

Issue counts:3
ARG_HINT_MISSING_SCRIPT:1
FUNCTION_HINT_MISSING:2
MISSING_VAR:2

Total issues:5
Total errors:2
Total infos:3

I've confirmed this to be a bug in 1.4.1 but looks fine in current 1.5.0-SNAPSHOT.


You can click through the combo boxes once again lol.

I'm just using the old way, just thought i'd let you know (y).

Fixed with https://github.com/Wando1423/Antario/commit/456030571615bd51f70e8891695923e7de7cc3dd.


possible regression and exception while handling link failures

Hi team,
While testing a link failure I got this exception below:
sdx-controller-1  | 2024-11-06T19:15:57.184862366Z INFO:sdx_pce.topology.temanager:generate_traffic_matrix, ports: ingress_port.id: urn:sdx:port:france.geant.org:geantFRS1:50, egress_port.id: urn:sdx:port:tenet.ac.za:tenetS1:50
sdx-controller-1  | 2024-11-06T19:15:57.184866594Z WARNING:sdx_pce.topology.temanager:No ingress node 'urn:sdx:node:france.geant.org:geantFRS1' found in the graph
sdx-controller-1  | 2024-11-06T19:15:57.184869104Z INFO:sdx_controller.handlers.connection_handler:Connection 1449c998-a41f-48c5-ae05-72fab1382e7c affected by link urn:sdx:link:interdomain:france.geant.org:geantFRS1:19:lhc.cern:lhcS1:19
sdx-controller-1  | 2024-11-06T19:15:57.215589498Z Exception in thread Thread-2:
sdx-controller-1  | 2024-11-06T19:15:57.215709422Z Traceback (most recent call last):
sdx-controller-1  | 2024-11-06T19:15:57.215722657Z   File "/usr/local/lib/python3.9/threading.py", line 980, in _bootstrap_inner
sdx-controller-1  | 2024-11-06T19:15:57.216056951Z     self.run()
sdx-controller-1  | 2024-11-06T19:15:57.216064705Z   File "/usr/local/lib/python3.9/threading.py", line 917, in run
sdx-controller-1  | 2024-11-06T19:15:57.216240156Z     self._target(*self._args, **self._kwargs)
sdx-controller-1  | 2024-11-06T19:15:57.216251556Z   File "/opt/venv/lib/python3.9/site-packages/sdx_controller/messaging/rpc_queue_consumer.py", line 135, in start_sdx_consumer
sdx-controller-1  | 2024-11-06T19:15:57.232771334Z     lc_message_handler.process_lc_json_msg(
sdx-controller-1  | 2024-11-06T19:15:57.239629866Z   File "/opt/venv/lib/python3.9/site-packages/sdx_controller/handlers/lc_message_handler.py", line 46, in process_lc_json_msg
sdx-controller-1  | 2024-11-06T19:15:57.239652286Z     self.connection_handler.handle_link_failure(
sdx-controller-1  | 2024-11-06T19:15:57.239660823Z   File "/opt/venv/lib/python3.9/site-packages/sdx_controller/handlers/connection_handler.py", line 271, in handle_link_failure
sdx-controller-1  | 2024-11-06T19:15:57.239669017Z     self.remove_connection(te_manager, connection["id"])
sdx-controller-1  | 2024-11-06T19:15:57.239676367Z   File "/opt/venv/lib/python3.9/site-packages/sdx_controller/handlers/connection_handler.py", line 208, in remove_connection
sdx-controller-1  | 2024-11-06T19:15:57.239683897Z     te_manager.delete_connection(service_id)
sdx-controller-1  | 2024-11-06T19:15:57.239690657Z   File "/opt/venv/lib/python3.9/site-packages/sdx_pce/topology/temanager.py", line 1056, in delete_connection
sdx-controller-1  | 2024-11-06T19:15:57.272020121Z     self.update_link_bandwidth(solution, reduce=False)
sdx-controller-1  | 2024-11-06T19:15:57.272033951Z   File "/opt/venv/lib/python3.9/site-packages/sdx_pce/topology/temanager.py", line 383, in update_link_bandwidth
sdx-controller-1  | 2024-11-06T19:15:57.272150259Z     connectionRequest, links = self.get_links_on_path(solution)
sdx-controller-1  | 2024-11-06T19:15:57.272161264Z   File "/opt/venv/lib/python3.9/site-packages/sdx_pce/topology/temanager.py", line 360, in get_links_on_path
sdx-controller-1  | 2024-11-06T19:15:57.272290720Z     assert src_node is not None
sdx-controller-1  | 2024-11-06T19:15:57.272315700Z AssertionError

the topology I’m using is this one:
https://github.com/atlanticwave-sdx/sdx-sc24-demo
I was thinking maybe this is related to that old problem when we create L2VPNs on switches that are on the border of the OXP
In The scenario above , all OXP have only one switch
The connection request was this one:
curl -X POST -H 'Content-type: application/json' http://$SDX_CONTROLLER:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "vlan from Tenet to France", "endpoints": [{"port_id": "urn:sdx:port:france.geant.org:geantFRS1:50", "vlan": "aby"}, {"port_id": "urn:sdx:port:tenet.ac.za:tenetS1:50", "vlan": "any"}]}'

$ $ curl http://$SDX_CONTROLLER:8080/SDX-Controller/l2vpn/1.0/29691d7c-9036-4687-8e85-d525392ba97a
{
  "29691d7c-9036-4687-8e85-d525392ba97a": {
    "archived_date": 0,
    "current_path": [
      {
        "port_id": "urn:sdx:port:france.geant.org:geantFRS1:50",
        "vlan": "4094"
      },
      {
        "port_id": "urn:sdx:port:france.geant.org:geantFRS1:19",
        "vlan": "4"
      },
      {
        "port_id": "urn:sdx:port:lhc.cern:lhcS1:19",
        "vlan": "4"
      },
      {
        "port_id": "urn:sdx:port:lhc.cern:lhcS1:16",
        "vlan": "4"
      },
      {
        "port_id": "urn:sdx:port:internet2.net:i2S1:16",
        "vlan": "4"
      },
      {
        "port_id": "urn:sdx:port:internet2.net:i2S1:14",
        "vlan": "4"
      },
      {
        "port_id": "urn:sdx:port:sax.net:saxS1:14",
        "vlan": "4"
      },
      {
        "port_id": "urn:sdx:port:sax.net:saxS1:12",
        "vlan": "4"
      },
      {
        "port_id": "urn:sdx:port:tenet.ac.za:tenetS1:12",
        "vlan": "4"
      },
      {
        "port_id": "urn:sdx:port:tenet.ac.za:tenetS1:50",
        "vlan": "4094"
      }
    ],
    "description": null,
    "endpoints": [
      {
        "port_id": "urn:sdx:port:france.geant.org:geantFRS1:50",
        "vlan": "4094"
      },
      {
        "port_id": "urn:sdx:port:tenet.ac.za:tenetS1:50",
        "vlan": "4094"
      }
    ],
    "name": "vlan test any--any",
    "service_id": "29691d7c-9036-4687-8e85-d525392ba97a"
  }
}

Thanks Italo! Two questions:
The topology links to a sdx-sc24-demo repo, could you include the topology jsons, from each of the OXP going to the LCs?
What are the exact steps to reproduce the error? Were you trying to place a connection and then delete the connection after it's been placed?

@italovalcy @congwang09 I guess one problem here is that we have not replaced that assert in pce with an actual error check.  Using assert is fine and perhaps necessary during development, but not when actually running things.  We could simply log the event and move on.
Does this make sense as a solution?  Link failures (or anything else) could always carry incomplete data. Data validation failures should not crash us.

We could have simply set PYTHONOPTIMIZE or ran Python with -O flag in production (and kept assert statements for development), instead of "manually" removing the asserts.
https://docs.python.org/3/using/cmdline.html#cmdoption-O
But that probably is a more error-prone strategy, in case someone forgets to do that when deploying...


Make public assist adds pub in front of pub(crate)

When the "Make public" assist is triggered on a reference to something in another crate that's currently pub(crate), the assist adds pub  in front of the pub(crate).
The assist should change the existing visibility modifier by removing the (crate).

I'm wondering if instead of "Make public" if we should have a "Change visibility" and present the user with the choices using a snippet.

Well, the assist knows the minimum required visibility to make the current code compile, so that's not necessary. Maybe the UI is different in VS code, but in vim (using coc.nvim), additional prompts from the assist completely block my input, so that doesn't sound very attractive to me right now. If the choices were presented very unobtrusively, I wouldn't mind though.


Retain zoom when high resolution image is loaded.

This is a common use case in photo viewer apps: first, a low-resolution image is downloaded and displayed, followed by the original high-resolution image.
Currently, in this library, if the user zooms in on the low-resolution image, the zoom position is reset when the high-resolution image is loaded later on.
        CoilZoomAsyncImage(
            model = request,
            contentDescription = "view image",
            modifier = Modifier.fillMaxSize(),
            zoomState = zoomState,
            onSuccess = {
                zoomState.zoomable.contentSize = it.painter.intrinsicSize.roundToIntSize() // how about locate?
            }
        )

I've tried like this, it doesn't seem to work. Is there any other way?

Yes, this is a known issue.
This is because ZoomImage relies on the original size of the image to calculate the step zoom ratio, and Coil's ImageResult does not include the original size of the image, so only ZoomImage can parse it. When you generate zoom during the parsing process, the zoom will be reset after the parsing is completed due to setting the original size of the image.
In addition, currently only the sketch image loader includes the original size of the image in the result, so the SketchZoomAsyncImage component of the zoomimage-compose-sketch4 module can avoid this problem.
[!TIP]

The step zoom ratios of other similar libraries are fixed, which is the difference between ZoomImage and them

Thanks for this amazing library.
I just tried with Sketch image loader.
 // Mock loading images
        var imagePaths by rememberSaveable {
          mutableStateOf(
            // First = high-res, second = low-res
            Pair<String, String?>(
              "file:///android_asset/thumbnail_cropped.jpeg",
              null
            )
          )
        }
        LaunchedEffect(Unit) {
          delay(1000)
          imagePaths = Pair(
            "file:///android_asset/smallSize.jpeg",
            "file:///android_asset/thumbnail.jpeg"
          )

          delay(2000)
          imagePaths = Pair(
            "file:///android_asset/fullSize.jpeg",
            "file:///android_asset/smallSize.jpeg"
          )
        }

        val imageState = rememberAsyncImageState(
          options = ImageOptions {
           // placeholder(MemoryCacheStateImage(imagePaths.second)) // nee
          }
        )
        SketchZoomAsyncImage(
          uri = imagePaths.first,
          state = imageState,
          zoomState = rememberSketchZoomState(),
          contentDescription = "view image",
          modifier = Modifier.fillMaxSize(),
        )

Here the zoom is retain if placeholder is used, but zoom level is not correct, and causes a jump.
Here are the images in case you want to test

Jumping issue.webm

Sorry, I misunderstood you.
I thought you meant to load only full-size images, double-click to zoom immediately after seeing the image, and wait for a while before the zoom is automatically reset.
If you use multiple images of different resolutions to allow users to see the image faster as in your example, and you also want to keep the zoom unchanged, I haven't considered this scenario. I think it may require multiple components to cooperate. I need to study this issue carefully before I can give you an answer.

Thanks. For your information, here's our scenario:

First, thumbnail is loaded from local file (150x150, 1:1 aspect ratio)
Then preview image is loaded, which is same aspect ratio of the original image but lower resolution, max 750px width
Finally the full size original image is loaded

Downloading and saving the image in app's local cache is handled by our SDK, and we use a Flow to observe when each file is ready to show to image view. Each step takes a few seconds depending on file size.
Our problem:

Preview image is loaded
User zooms on it
Full size image is loaded
Zoom level and pan is reset.

I also tried using ThumbnailMemoryCacheStateImage, it didn't work perfectly.
Please let me know if you need more information or any support.

The existing logic of ZoomImage is that any change in the image uri, painterSize, or contentOriginSize will reset the image, because painterSize and contentOriginSize need to be involved in calculating the step zoom factor and the maximum and minimum boundary zoom factors. A simple and rough reset when the zoom factor changes can avoid many bugs.
The currently available methods are:
// 1. Make sure that the cache of "file:///android_asset/thumbnail.jpeg" is already in the memory cache
// 1.1 If you are redirected from the list page, and the list page has already loaded "file:///android_asset/thumbnail.jpeg"
// 1.2 Otherwise, you need to actively load it into the memory cache, refer to the document:https://github.com/panpf/sketch/blob/main/docs/wiki/preload.md

// 2.
SketchZoomAsyncImage(
  request = ComposableImageRequest("file:///android_asset/fullSize.jpeg") {
    placeholder(ThumbnailMemoryCacheStateImage("file:///android_asset/thumbnail.jpeg"))
  },
  contentDescription = "view image",
  modifier = Modifier.fillMaxSize(),
)

When I set the placeholder like this, it does a complete zoom reset.
ComposableImageRequest(imagePath) {
        placeholder(ThumbnailMemoryCacheStateImage(previousImagePath))
        crossfade(fadeStart = false)
      },

However, if I set like this inside ImageOptions, it tries to retain the zoom but not accurately works
    val imageState = rememberAsyncImageState(
      options = ImageOptions {
        placeholder(ThumbnailMemoryCacheStateImage(previousImagePath))
      }
    )

Yes, it will be reset. Let me work on how to keep the zoom information as much as possible.

Thank you so much, eagerly waiting for it. No other zoomable subsampling compose library supports this yet. This can distinguise ZoomImage from other libraries.
Also please check if rememberSavable with a custom Saver can be implemented to survive configuration change like rotation. Telephoto library has this implemented.

Hi, this issue seems to also apply when switching between images of exact same size. Is there a way to work around it in this case?

Hi, this issue seems to also apply when switching between images of exact same size. Is there a way to work around it in this case?

Yes, it will reset as long as the image is switched, the logic is like this.
Imagine that when switching images in ViewPager, although the image size is the same, it also needs to be reset
So what is your demand scenario? Why do you need to keep the zoom unchanged when switching images?

Hi, this issue seems to also apply when switching between images of exact same size. Is there a way to work around it in this case?

Yes, it will reset as long as the image is switched, the logic is like this.
Imagine that when switching images in ViewPager, although the image size is the same, it also needs to be reset
So what is your demand scenario? Why do you need to keep the zoom unchanged when switching images?

I am trying to display a metro map on wearos, and I wish to switch to an ambient version when the watch goes into ambient mode, without the zoom and panning resetting.

As a library, we should try to ensure that only common functions are added to the library. For the same size switching of pictures of the same size may only be a rare case. I have to consider more about how to handle the transition of zoom and pan information when switching to pictures of different sizes. I don’t have a particularly good solution for this part, so there has been no progress. If you have a suitable solution, we can discuss it together.
Let’s solve your problem first. You can refer to the usage of ZoomImage in BasicZoomImageSample, manually load the picture and set contentSize and setSubsamplingImage, and then only modify painter and setSubsamplingImage when switching pictures.

As a library, we should try to ensure that only common functions are added to the library. For the same size switching of pictures of the same size may only be a rare case. I have to consider more about how to handle the transition of zoom and pan information when switching to pictures of different sizes. I don’t have a particularly good solution for this part, so there has been no progress. If you have a suitable solution, we can discuss it together.
Let’s solve your problem first. You can refer to the usage of ZoomImage in BasicZoomImageSample, manually load the picture and set contentSize and setSubsamplingImage, and then only modify painter and setSubsamplingImage when switching pictures.

Is it possible to call setSubsamplingImage without causing the image zoom and pan to reset?

Yes, you just need to make sure that the image size is consistent, or the size in ImageInfo is consistent, because contentOriginSize comes from them, and it will not be reset as long as contentOriginSize does not change


compose-shimmer-android depends on org.jetbrains.compose.*

The Gradle Module Metadata of compose-shimmer-android is not aligned with the pom.

compose-shimmer-android-1.2.0.pom
compose-shimmer-android-1.2.0.module

The former declares a dependency on org.jetbrains.compose.*, the latter on androidx.compose.*.
Since the Gradle Module Metadata has higher priority, Android apps are pulling in Jetbrains' version of Compose.

Just had the time to have a deeper look into this topic. I'm not sure if it is even possible to make the change you are asking for. Coil 3, which is in alpha right now, has become a multiplatform library as well. And even their .module points to org.jetbrains.compose.*.
Do you know how to make it work?

I haven't dipped my toes into the Kotlin Multiplatform world yet, so I'm not sure how all of this should work, but looking at this better, I think the libraries from Jetbrains are there simply to pull in the actual library for the selected target.
For example, this is what the dependency graph shows:
+--- com.valentinilk.shimmer:compose-shimmer:1.2.0
|    \--- com.valentinilk.shimmer:compose-shimmer-android:1.2.0
|         +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10 (*)
|         +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.9.10 -> 1.9.20 (*)
|         +--- org.jetbrains.compose.runtime:runtime:1.5.3
|         |    \--- androidx.compose.runtime:runtime:1.5.0 -> 1.5.4 (*)
|         +--- org.jetbrains.compose.foundation:foundation:1.5.3
|         |    \--- androidx.compose.foundation:foundation:1.5.0 -> 1.5.4 (*)
|         +--- org.jetbrains.compose.ui:ui:1.5.3
|         |    \--- androidx.compose.ui:ui:1.5.0 -> 1.5.4 (*)

I also only see a bunch of knm files inside of org.jetbrains.compose.runtime:runtime.
It's weird that the dependency does not show up in the pom, but I should really be looking at the .module file when using Gradle.
If anything, this would be a bug of gradle-maven-publish-plugin, if this is really a bug.