ShortCut can be used only with InputEvents

While working on the CanvasItemEditor, I figured out that a lot of keyboard "shortcuts" were hardcoded into the code, and thus could not be modified in the editor preferences.
The problem is the following: the ShortCut node (scene/gui/input_action.h) has an is_shortcut(const Ref<InputEvent> &p_event) function to test whether or not an InputEvent corresponds to the recorded shortcut. However, there is no way to test is the keys in the shortcut are currently pressed or not (like with Input::get_sigleton()->is_key_pressed()), unless using something like in spatial_editor_plugin.cpp:
int key_left = ED_GET_SHORTCUT("spatial_editor/freelook_left")->get_shortcut()->cast_to<InputEventKey>()->get_scancode();
if (input.is_key_pressed(key_left)) {
...
}

The problem is that this code does not handle shortcuts with key modifiers (ctrl, alt, shift) :/. Also, shortcuts using mouse buttons instead of keyboards key would not work.
I can see those two solutions to the problem:

We implement a is_pressed() function in the ShortCut interface.
We implement an is_key_pressed_with_modifiers() function in the Input interface

What's the problem with using is_shortcut? That's the way it's done everywhere in the editor and it also handles modifiers.
If we add a function to get the shortcut state outside of  _input() you won't be able to set the events as handled for the node that checks it, making overlapping shortcuts for different parts of the editor impossible. (Or very hacky I guess)

The problem is that with is_shortcut, you need an InputEvent.
If you have a look to editor/plugins/canvas_item_editor.cpp (I am working of this file :) ) you can see there are actually a lot of keys checked with Input::get_singleton()->is_pressed(KEY_...), especially when dealing with mouse events. As an example, when moving the mouse with button left pressed, we check if the space bar is pressed or not to check whether to pan the view or not. Thus, while we are dealing with a mouse motion event, we need to poll the keys state. If we want to make the KEY bindable within the editor preferences, we have no other way to use ED_SHORTCUT(...), which keys cannot be polled for the current states as it needs an InputEvent.
Indeed, we could use a boolean to store the status of the shortcut (set to true when we detect a pressed event, and to false when we have a release one), but this is tedious in most cases.

If we add a function to get the shortcut state outside of _input() you won't be able to set the events as handled for the node that checks it, making overlapping shortcuts for different parts of the editor impossible. (Or very hacky I guess)

I dont know for that, if we define the shorcut with ED_SHORTCUT, probably that the event get caught anyway.

Feature and improvement proposals for the Godot Engine are now being discussed and reviewed in a dedicated Godot Improvement Proposals (GIP) (godotengine/godot-proposals) issue tracker. The GIP tracker has a detailed issue template designed so that proposals include all the relevant information to start a productive discussion and help the community assess the validity of the proposal for the engine.
The main (godotengine/godot) tracker is now solely dedicated to bug reports and Pull Requests, enabling contributors to have a better focus on bug fixing work. Therefore, we are now closing all older feature proposals on the main issue tracker.
If you are interested in this feature proposal, please open a new proposal on the GIP tracker following the given issue template (after checking that it doesn't exist already). Be sure to reference this closed issue if it includes any relevant discussion (which you are also encouraged to summarize in the new proposal). Thanks in advance!


code style: disallow number leading zero

In this PR I added a number-leading-zero rule to stylelint config to disallow a leading zero for fractional numbers less than 1.
The following pattern is considered as a problem:
a { line-height: 0.5; }
The following pattern isn't considered as a problem:
a { line-height: .5; }
Closes #1125

:tada: This PR is included in version 4.0.0-beta.18 :tada:
The release is available on:

npm package (@beta dist-tag)
GitHub release

Your semantic-release bot :package::rocket:


[libopenmpt] Upgrade to 0.5.10, include author feedback

This PR addresses feedback given by @manxorist in https://github.com/microsoft/vcpkg/pull/2669 and https://github.com/microsoft/vcpkg/issues/18480, while also upgrading the library to version 0.5.10.
The new port provides both CMake and pkg-config integration.
In order to provide CMake integration on Linux, this PR also fixes https://github.com/microsoft/vcpkg/issues/15551 which causes mpg123 to provide CMake integration on Linux instead of just Windows.

We generally err on the side of overlinking to make sure things work. It seems that --as-needed is becoming a more-and-more common practice (and is the default with MSVC), which removes almost all of the downsides.
I think I've addressed all your feedback -- thank you very much for giving it and sorry for the very long turnaround on this!

I think I've addressed all your feedback -- thank you very much for giving it and sorry for the very long turnaround on this!

Thanks!
libopenmpt is at version 0.5.11 by now, so I guess you could also update that. See https://lib.openmpt.org/libopenmpt/2021/08/22/security-updates-0.5.11-0.4.23-0.3.32/. Should require no build related changes.

Looks good to me now.


Confusing message when trying to access a field that does not exist in model

When I was teaching Elm to a friend, he accidentally tried to access a field "countt" that don't exist.
But he was not able to understand the error message!
Something like "Field countt seems to not exist in model" would be better!
import Html            exposing (..)
import Html.Attributes exposing (..)
import Html.Events     exposing (onClick)
import Html.App        exposing (beginnerProgram)

type Msg = Inc | Dec
type alias Model = { count : Int }

view : Model -> Html Msg
view model =
    div [] [ button [ onClick Inc ] [ text "+" ]
           , br [] []
           , text <| toString model.count
           , br [] []
           , button [ onClick Dec ] [ text "-" ]
           ]

update : Msg -> Model -> Model
update msg model =
    case msg of
        Inc ->
            { model | count = model.count + 1 }
        Dec ->
            { model | count = model.countt - 1 }

main : Program Never
main =
    beginnerProgram { model = Model 0, view = view, update = update }

Thanks for the report! Follow along in #154. That will make it so this would trigger the normal record mismatch errors.

I got it down to a smaller http://sscce.org/
type Msg = Increment | Decrement

type alias Model = { count : Int }

update : Msg -> Model -> Model
update msg model =
  case msg of
    Increment ->
      { model | count = model.count + 1 }

    Decrement ->
      { model | count = model.countt - 1 }

Here is the new error message:

This is the result of assuming the type annotation is correct and the changes in https://github.com/elm-lang/elm-compiler/commit/b17a4f051af5780950b790eb50ecb4093c699ab0 specific to trying to access fields that do not exist.


Is there a way to Convert Owl-ViT to ONNX to be later converted to TensorRT?

Thanks for your amazing work.  Are you planning on releasing a way to convert Owl-ViT to ONNX?

We have a colab that shows how to convert the JAX model to a TensorFlow tf.SavedModel. I believe you can then convert the tf.SavedModel to TensorRT with something like this (I haven't tested this):
params = tf.experimental.tensorrt.ConversionParams(precision_mode='FP32')
converter = tf.experimental.tensorrt.Converter(input_saved_model_dir=model_dir, conversion_params=params)
converter.convert()

Please let us know if that works!

Hi @mjlm, I've tried and this is the output.
################################################################################
TensorRT unsupported/non-converted OP Report:
        - Identity -> 5x
        - NoOp -> 2x
        - Placeholder -> 2x
        - StatefulPartitionedCall -> 1x
--------------------------------------------------------------------------------
        - Total nonconverted OPs: 10
        - Total nonconverted OP Types: 4
For more information see https://docs.nvidia.com/deeplearning/frameworks/tf-trt-user-guide/index.html#supported-ops.
################################################################################

2023-03-28 17:19:16.894536: W tensorflow/compiler/tf2tensorrt/segment/segment.cc:1298] The environment variable TF_TRT_MAX_ALLOWED_ENGINES=20 has no effect since there are only 0 TRT Engines with  at least minimum_segment_size=3 nodes.
2023-03-28 17:19:16.894625: I tensorflow/compiler/tf2tensorrt/convert/convert_graph.cc:799] Number of TensorRT candidate segments: 0
Segmentation fault

I'm not gonna try to fix it as finding and replacing the unsupported ops might take quite a while.
Just wanted to let you know. Amazing work by the way.


[BUG 🪲] Unable to save frame as an image

Describe the bug 🐛
I'm not sure if your library is to blame or some wonkiness with the Windows crates/ my version of Windows. I was following the example in the README, added windows-capture v1.4.0 to my project and copied the example into my main.rs file. It runs as expected and saves a 6 second clip. If I uncomment the line frame.save_as_image("frame.png", ImageFormat::Png)?; and import the required Type. I get an error: Screen Capture Failed: FrameHandlerError(WindowsError(Error { code: HRESULT(0x80070057), message: "The parameter is incorrect." }))
I tried to dig into it a bit, but I'm fairly new to Rust and don't understand Windows APIs much at all. It seems to be coming from the frame.buffer function during the texture_desc declaration. I was able to get past the error then if I hard coded the Format from DXGI_FORMAT(self.color_format as u32) to just be DXGI_FORMAT(28) (Rgba8 default). I also was able to change the underlying DXGI_FORMAT struct to handle i32 instead of u32 and changed all of the formats to align as well and that also resolved this issue.
However, even after I hardcode that value it makes it to the self.context.Map function to "Map the texture to enable CPU access" with the same error as above and seems to be something with the D3D11_MAPPED_SUBRESOURCE::default(), but that's where it gets into the Windows API and I'm really not sure of anything there. So this also makes me think it might not be an issue with your crate.
Expected behavior 📝
I expect to get an image saved and overwritten with each frame that's captured during the 6 second recording
OS 🤖

Version: 11
Build: 23H2

Also facing this issue...

@BenedictWilkins Out of curiosity what version and build of windows are you using?

@WallyOxen
OS Name	Microsoft Windows 11 Home
Version	10.0.22631 Build 22631
did reverting to that commit not work for you?

@BenedictWilkins I was just now able to test it out. After messing with the missing capture::Context I was indeed able to get it to output screenshots

It seems that this commit changed frame.rs:205 and removed the D3D11_CPU_ACCESS_WRITE.0 as u32 flag. If I add that back in things work as well

It seems that this commit changed frame.rs:205 and removed the D3D11_CPU_ACCESS_WRITE.0 as u32 flag. If I add that back in things work as well

@WallyOxen Ha ha ha, I created this commit, I removed the CPU writable flag and didn't realize it would affect other places.
But what I'm wondering is that adding writable flags to texture doesn't seem to make much sense, right? Realistically there shouldn't be a need to do a write operation to a captured texture.

https://github.com/NiiightmareXD/windows-capture/blob/0f220752f94843e850f0503834298625fc0921f6/src/frame.rs#L337
I think I know why, I didn't realize that I would wrap the texture's buffer in &mut [u8], and in a screen capture scenario it would not normally be written to an already captured texture.
Sorry, I was going to have the writable flag removed because it didn't make sense, but it doesn't look like I can do that.

@NiiightmareXD It looks like you need to do a quick fix to fix this, there is an issue with my merge request.

#94  I created a bug fix waiting to be merged.

I will publish the new version and the problem should be fixed.

Thanks for your recent help @mycrl, I will invite you to collaborators.


Radio Button is broken with RHL

I'm experiencing an issue with RadioGroup and react-hot-loader together.

isComponentOfType is overwritten in my case. If I remove RHL, it works.
this is caused by the fact, that isComponentOfType in RadioGroup is loaded from utils/react instead of utils/is-component-of-type and is not overwritable.

Hi,
I added the actual beta.8 from repo to my app ... but the problem is stell actual ...

I updated to beta.8 and for me it looks ok with RHL 3

you are able to check the radios?

code cools like this:
import { RadioGroup, RadioButton } from 'react-toolbox/lib/radio';
 <RadioGroup name='steptype' value={this.state.value} onChange={this.handleChange}>
     <RadioButton label={I18n.t('processes.new.processStepTypeDuty')} value='duty'/>
      <RadioButton label={I18n.t('processes.new.processStepTypeVariable')} value='variable'/>
      <RadioButton label={I18n.t('processes.new.processStepTypeOptioanal')} value='optional'/>
 </RadioGroup>

Having this issue with beta.12 and rhl 4.0.0. Is there any solution?


Add label to the list of PR changes

It would be nice to be able to see which pull requests resulted in minor or major versions.
It is easier to know which Pull Requests to refer to when manually compiling topics to be added to the release notes.

I was able to categorize the release notes by specifying changelog.categories[*].title and changelog.categories[*].labels in the .github/release.yml file by referring to the following article.
https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes


LED command has all zero parameters

In the current version the LED command uses all zero's as it's parameters which is not valid (PD returns NAK 9.)

Are you referring to the console sending the LED command? The console will send zero the time/timer parameters to keep the color permanant.
I'm able to send LED command to a Wavelynx reader successfully.

not how the spec reads to others.  this looks wrong, will follow up.

The OSDP.Net lib doesn't restrict the input value of the timer fields. There shouldn't be any change needed for the library itself. The documentation will need to be updated to properly state the proper values for the LED command.

This has been resolved with version 2.0.12


[Button] Add react-router link support in typescript

The typescript typings did not support the ability to use to if we assume that React Router links should work in TS land.

[x] PR has tests / docs demo, and is linted.
[x] Commit and PR titles begin with [ComponentName], and are in imperative form: "[Component] Fix leaky abstraction".
[x] Description explains the issue / use-case resolved, and auto-closes the related issue(s) (http://tr.im/vFqem).

This solution won't scale to all the properties available. We gonna need something else.


$snapshot object does not exist

https://github.com/GoogleCloudPlatform/php-docs-samples/blob/eec5f5ca0c7757a9ef7afaeeeaa3c60228393f44/firestore/src/get_multiple_docs.php#L50

Closing because of a lack of description. Please open a new issue and describe what you did, what happened as a result, and what you expect to happen


Update pykms_Server.py

Fixed incorrect Boolean, now aligns with the description of “deactivated by default”.
Resolves #108

Sooo, why was this closed?

Because it sat there for three weeks without being looked at, and to have a PR open, I have to have the repo forked on my account. It really is such a simple fix for a silly problem, it feels like a PR for it isn't even necessary, could fix it in two seconds in the web editor.

Oh, well. I see. I've pushed it to next. Thanks!


Use common queue names

From https://hpcbios.readthedocs.org/en/latest/HPCBIOS_05-05.html

I guess we need to keep the grid queue.
Been thinking of adding a for loop to the slurm.conf.j2 to add partitions from a list of dicts.
Maybe now would be a good time to implement that.

I've been thinking of the same. Also for nodes, since we have heterogeneous nodes so we need several NodeName=... lines in slurm.conf.
If one doesn't want to break sites running with the current out-of-the-box setup, one could do something like
{% if slurm_nodelist is defined %}
Loop over a list of maps, each of which generates one "NodeName=" line in the conf file.
{% else %}
Use the current variables
{% endif %}
?

Yes. Shall we add all partition settings with | default('value') }} too?  or should it just be a dictionary of nodes and one argument with all partition settings a site wants to set?

Hmm, maybe there's no particular value in specifying all kinds of parameters as separate keys, just put everything in a string? E.g. some YAML like
slurm_nodelist:
- "NodeName=pe[1-1234]  RealMemory=NNN Feature=haswell"
- "NodeName=ivy[1-48] RealMemory=MMM Feature=ivybridge"
- "NodeName=gpu[23-25] Gres=gpu:4 Feature=haswell,teslak80"
- etc...
and similar for partition configs? That would be the easiest, at least.
I don't think we need to worry about defaults, since if slurm_nodelist isn't defined the site just get the current defaults anyway?

Agreed. Is also less maintenance needed on the role to support newer slurms. I'll have a look at this tomorrow.


Added PR template

resolved: #732
details:
Moves template to specific folder

@sahitpj  Thanks!!
We have a lot of interesting issues!!
How about challenge other issues?!!
I will translate all issues written in korean.

Yeah sure , that would be nice, Thank you !


chats: added openAi chat generation as LLM, fixes #43

PR Checklist

[x] Read the Contributing documentation.
[x] Read the Code of conduct documentation.
[x] Name your Pull Request title clearly, concisely, and prefixed with the name of primarily affected package you changed according to Good commit messages (such as memory: add interfaces for X, Y or util: add whizzbang helpers).
[ ] Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
[ ] Provide a description in this PR that addresses what the PR is solving, or reference the issue that it solves (e.g. fixes #123).
[ ] Describes source of new concepts.
[ ] References existing implementations as appropriate.
[ ] Contains test coverage for new functions.
[ ] Passes all golangci-lint checks.
[ ] (remove and do not use this row unless you are a trusted contributor) I am an existing
contributor.

This, as is, not compatible with the internal API of this library. That's why this is a draft and doesn't include tests or anything. I would like to discuss how to proceed.
To test the implementation, use the following main.go file:
https://gist.github.com/ChristianSch/20251608147883cd5c6752988f16eb8e

I'm going to accept 56 and we can refactor this as needed.

This is solved in other work/ merged PRs.


POST throws timeout error, even though it gets response

I'm seeing something that has me very confused. I'm making this request:
            match self
                .client    // A reqwest::blocking::Client
                .post(&self.url)
                .header(CONTENT_TYPE, "application/json")
                .body(request_json.to_string())
                .send()

The server receives the request, and replies as seen in the server logs:
[2021-03-11T01:19:34.370440100Z TRACE jsonrpc_core::io] Request: {"id":1,"jsonrpc":"2.0","method":"getSlot","params":[{"commitment":"confirmed"}]}.
[2021-03-11T01:19:34.370516100Z DEBUG jsonrpc_core::io] Response: {"jsonrpc":"2.0","result":73,"id":1}.

This response gets registered in the client's logs for the request:
2021-03-11T01:19:34.369761900+00:00 [DEBUG] (12) hyper::client::pool: reuse idle connection for ("http", <IP_ADDRESS>:8899)
2021-03-11T01:19:34.370162600+00:00 [DEBUG] (12) hyper::proto::h1::io: flushed 189 bytes
2021-03-11T01:19:34.371146500+00:00 [DEBUG] (12) hyper::proto::h1::io: parsed 3 headers
2021-03-11T01:19:34.371245700+00:00 [DEBUG] (12) hyper::proto::h1::conn: incoming body is content-length (37 bytes)
2021-03-11T01:19:34.371366300+00:00 [DEBUG] (12) hyper::proto::h1::conn: incoming body completed
2021-03-11T01:19:34.371491600+00:00 [DEBUG] (12) hyper::client::pool: pooling idle connection for ("http", <IP_ADDRESS>:8899)
2021-03-11T01:19:34.371842600+00:00 [DEBUG] (12) reqwest::async_impl::client: response '200 OK' for http://<IP_ADDRESS>:8899/

and yet, that code returns an Err:
    ....
    8: error sending request for url (http://<IP_ADDRESS>:8899/): operation timed out
    9: operation timed out   // Bottom of stacktrace

How can this be?

Thanks for the quick response @seanmonstar ! Yep, it's those very small bodies. The timeout is configured to 30s in the containing class:
const REQUEST_TIMEOUT: Duration = Duration::from_secs(30);

pub struct HttpSender {
    client: Client,
    url: String,
}

impl HttpSender {
    pub fn new(url: String) -> Self {
        Self::new_with_timeout(url, REQUEST_TIMEOUT)
    }

    pub fn new_with_timeout(url: String, timeout: Duration) -> Self {
        let client = Client::builder()
            .timeout(timeout)
            .build()
            .expect("build rpc client");

        Self { client, url }
    }
}

The timeout does seem to be getting hit though - the "200 OK" line shows up exactly 30 seconds before the outer ERROR logline that indicates the error bubbling up:
2021-03-11T01:42:32.374972200+00:00 [DEBUG] (1) testsuite::testsuite_impl::network_partition_test: Getting current slot for bootstrapper 4...
2021-03-11T01:42:32.375125600+00:00 [DEBUG] (14) hyper::client::pool: reuse idle connection for ("http", <IP_ADDRESS>:8899)
2021-03-11T01:42:32.375447800+00:00 [DEBUG] (14) hyper::proto::h1::io: flushed 189 bytes
2021-03-11T01:42:32.376161400+00:00 [DEBUG] (14) hyper::proto::h1::io: parsed 3 headers
2021-03-11T01:42:32.376343100+00:00 [DEBUG] (14) hyper::proto::h1::conn: incoming body is content-length (37 bytes)
2021-03-11T01:42:32.376526500+00:00 [DEBUG] (14) hyper::proto::h1::conn: incoming body completed
2021-03-11T01:42:32.376948200+00:00 [DEBUG] (14) hyper::client::pool: pooling idle connection for ("http", <IP_ADDRESS>:8899)
2021-03-11T01:42:32.377083600+00:00 [DEBUG] (14) reqwest::async_impl::client: response '200 OK' for http://<IP_ADDRESS>:8899/
2021-03-11T01:43:02.351775400+00:00 [ERROR] An error occurred running the test suite executor:
2021-03-11T01:43:02.352409600+00:00 [DEBUG] (4) h2::codec::framed_write: send frame=GoAway { error_code: NO_ERROR, last_stream_id: StreamId(0) }
2021-03-11T01:43:02.355093400+00:00 [DEBUG] (4) h2::proto::connection: Connection::poll; connection error error=NO_ERROR
Error: An error occurred running the test suite executor

Caused by:
    0: An error occurred running the test execution flow
    1: An error occurred setting up & executing test 'networkPartitionTest'
    2: An error occurred executing the test
    3: An error occurred while waiting for the cluster slots to start advancing again
    4: An error occurred getting the current confirmed slots for the bootstrappers
    5: An error occurred getting the current confirmed slot for bootstrapper 4
    6: An error occurred getting the confirmed slot
    7: An error occurred sending the request
    8: error sending request for url (http://<IP_ADDRESS>:8899/): operation timed out
    9: operation timed out

One thing worth noting - I'm making a bunch of JSON RPC requests in sequence (synchronously), and it doesn't always fail on the same one. E.g. in this stacktrace that I took just now, it was node <IP_ADDRESS>, whereas in the stacktrace above is was <IP_ADDRESS>

Huh, so what returns the actual timeout error? I'm guessing in your code you've received the Response, and then after that you try to read the body, and that call is what hangs and then times out?

Yep, this is the full match statement:
            match self
                .client
                .post(&self.url)
                .header(CONTENT_TYPE, "application/json")
                .body(request_json.to_string())
                .send()
            {
                Ok(response) => {
                    if !response.status().is_success() {
                        if response.status() == StatusCode::TOO_MANY_REQUESTS
                            && too_many_requests_retries > 0
                        {
                            too_many_requests_retries -= 1;
                            debug!(
                                "Server responded with {:?}, {} retries left",
                                response, too_many_requests_retries
                            );

                            // Sleep for 500ms to give the server a break
                            sleep(Duration::from_millis(500));
                            continue;
                        }
                        return Err(response.error_for_status().unwrap_err().into());
                    }

                    let json: Value = serde_json::from_str(&response.text()?)?;
                    if json["error"].is_object() {
                        return Err(anyhow!(
                            "An error occurred making the JSON RPC request: {}",
                            json["error"].clone(),
                        ));
                    }
                    return Ok(json["result"].clone());
                }
                Err(err) => {
                    return Err(err.into());
                }
            }

AFAICT it's the actual send that goes straight into the outer Err arm (though will add some extra debugging to verify)

One other thing - I hit a very similar issue with tonic; might be related: https://github.com/hyperium/tonic/issues/575

Yep, just confirmed with extra debugging @seanmonstar - it's the
                Err(err) => {
                    return Err(err.into());
                }

arm that's getting hit; the error is getting thrown by this piece of code:
                .client
                .post(&self.url)
                .header(CONTENT_TYPE, "application/json")
                .body(request_json.to_string())
                .send()

It's not even making it to the body-reading Ok() arm

Hm, you mention tonic... are you using this in an async context? I mean, if you were, I'd expect you'd have hit the debug_assert trying to catch that, but if it didn't trigger, it's really easy for that mixture to cause a deadlock...

I'll have to beg some ignorance here as I'm a bit of a Rust newb - I have #[tokio::main] on my main function; does that make it async?

And actually, this reminds me that using prost-generated client code elsewhere in the codebase (unrelated to reqwest call above) wouldn't work without that, which I think means that it is an async context (?)

Yes it does (you had to make it async fn main). Can you switch to using the async reqwest client?

Will give that a go! Question though - what's actually happening, that causes this behaviour? It seems like in both the tonic and this case, once I make a certain number of requests then things get frozen. Before that point, everything works fine

And actually a followon question: I control the BlockingClient for now due to a hackaround I'm doing, but that code actually comes from a library I don't control. This would mean that my tonic gRPC clients are async, but this library is sync. How do I resolve that discrepancy?

@seanmonstar I switched to using the async client and now I'm seeing exactly the same behaviour as in https://github.com/hyperium/tonic/issues/575 - the request gets received, but then h2 holds on to it forever:
2021-03-11T03:09:22.545098300+00:00 [DEBUG] (1) hyper::client::pool: reuse idle connection for ("http", <IP_ADDRESS>:8899)
2021-03-11T03:09:22.545273800+00:00 [DEBUG] (3) hyper::proto::h1::io: flushed 189 bytes
2021-03-11T03:09:22.545723+00:00 [DEBUG] (4) hyper::proto::h1::io: parsed 3 headers
2021-03-11T03:09:22.546106+00:00 [DEBUG] (4) hyper::proto::h1::conn: incoming body is content-length (37 bytes)
2021-03-11T03:09:22.546312900+00:00 [DEBUG] (4) hyper::proto::h1::conn: incoming body completed
2021-03-11T03:10:59.000939100+00:00 [DEBUG] (3) h2::codec::framed_read: received frame=GoAway { error_code: NO_ERROR, last_stream_id: StreamId(2147483647) }
2021-03-11T03:10:59.001087200+00:00 [DEBUG] (3) h2::codec::framed_read: received frame=Ping { ack: false, payload: [1, 6, 1, 8, 0, 3, 3, 9] }
2021-03-11T03:10:59.001290300+00:00 [DEBUG] (3) h2::codec::framed_write: send frame=Ping { ack: true, payload: [1, 6, 1, 8, 0, 3, 3, 9] }
2021-03-11T03:10:59.001711100+00:00 [DEBUG] (3) h2::codec::framed_write: send frame=GoAway { error_code: NO_ERROR, last_stream_id: StreamId(0) }
2021-03-11T03:10:59.001799600+00:00 [DEBUG] (3) h2::proto::connection: Connection::poll; connection error error=NO_ERROR

That minute-and-a-half gap between 09:22 and 10:59 seems to be a perpetual hang inside h2 or somewhere - the GoAway that finally unblocks it is a timeout in my code that shuts down the server the client is talking to. If I extend that timeout (below), you can see that h2 will never return and the time between the last message and the GoAway will extend but my code will never get control back:
2021-03-11T03:41:43.354133+00:00 [DEBUG] (1) hyper::client::pool: reuse idle connection for ("http", <IP_ADDRESS>:8899)
2021-03-11T03:41:43.354525500+00:00 [DEBUG] (4) hyper::proto::h1::io: flushed 189 bytes
2021-03-11T03:41:43.355227800+00:00 [DEBUG] (4) hyper::proto::h1::io: parsed 3 headers
2021-03-11T03:41:43.355398+00:00 [DEBUG] (4) hyper::proto::h1::conn: incoming body is content-length (37 bytes)
2021-03-11T03:41:43.356124700+00:00 [DEBUG] (4) hyper::proto::h1::conn: incoming body completed
2021-03-11T03:41:43.356769800+00:00 [DEBUG] (4) hyper::client::pool: pooling idle connection for ("http", <IP_ADDRESS>:8899)
2021-03-11T03:41:43.357463600+00:00 [DEBUG] (1) reqwest::async_impl::client: response '200 OK' for http://<IP_ADDRESS>:8899/
2021-03-11T03:41:43.357518800+00:00 [DEBUG] (1) testsuite::services_impl::validator::http_sender: Got OK response from send...
2021-03-11T03:41:43.357538100+00:00 [DEBUG] (1) testsuite::services_impl::validator::http_sender: About to read response body...
2021-03-11T03:41:43.357932700+00:00 [DEBUG] (1) testsuite::testsuite_impl::network_partition_test: Bootstrapper 2's current slot is 74
2021-03-11T03:41:43.357959800+00:00 [DEBUG] (1) testsuite::testsuite_impl::network_partition_test: Getting current slot for bootstrapper 3...
2021-03-11T03:41:43.358104900+00:00 [DEBUG] (1) hyper::client::pool: reuse idle connection for ("http", <IP_ADDRESS>:8899)
2021-03-11T03:41:43.358705600+00:00 [DEBUG] (4) hyper::proto::h1::io: flushed 189 bytes
2021-03-11T03:41:43.359773400+00:00 [DEBUG] (4) hyper::proto::h1::io: parsed 3 headers
2021-03-11T03:41:43.360632600+00:00 [DEBUG] (4) hyper::proto::h1::conn: incoming body is content-length (37 bytes)
2021-03-11T03:41:43.361271900+00:00 [DEBUG] (4) hyper::proto::h1::conn: incoming body completed
2021-03-11T03:45:18.604356700+00:00 [DEBUG] (5) h2::codec::framed_read: received frame=GoAway { error_code: NO_ERROR, last_stream_id: StreamId(2147483647) }
2021-03-11T03:45:18.604929900+00:00 [DEBUG] (5) h2::codec::framed_read: received frame=Ping { ack: false, payload: [1, 6, 1, 8, 0, 3, 3, 9] }
2021-03-11T03:45:18.605298400+00:00 [DEBUG] (5) h2::codec::framed_write: send frame=Ping { ack: true, payload: [1, 6, 1, 8, 0, 3, 3, 9] }
2021-03-11T03:45:18.606043100+00:00 [DEBUG] (5) h2::codec::framed_write: send frame=GoAway { error_code: NO_ERROR, last_stream_id: StreamId(0) }
2021-03-11T03:45:18.606491800+00:00 [DEBUG] (5) h2::proto::connection: Connection::poll; connection error error=NO_ERROR
2021-03-11T03:45:18.609186200+00:00 [DEBUG] (5) hyper::proto::h2::client: connection error: Socket not connected (os error 107)

I switched to using the async client and it sometimes works, but now I'm seeing exactly the same behaviour as in hyperium/tonic#575

Hm, when I read through the tonic issue, I notice a bunch more block_on calls. Are those also being called inside an async context? Calling block_on inside some Future (like an async fn, or a function that async fn calls) can cause deadlocks. Can you change those to awaits?

what's actually happening, that causes this behaviour?

Do you mean how a blocking API (like block_on, or reqwest::blocking (which uses block_on internally)) can cause a deadlock? I can wax on a little. So, block_on works by trying to poll the future for readiness. If the future happens to be ready, then nothing bad happens. If it isn't ready, then block_on will park the thread until that Future signals it is ready. The problem is that usually, that same Future is expecting the same thread to eventually check the IO driver (probably backed by epoll), and when the OS through epoll says the socket is ready, it signals the Future to be polled again. If the thread is parked (std::thread::park()), then it can't also check the IO driver for a socket status, and so it can deadlock.

Ohh that's super fascinating - block_on can't be used inside an async context??? I'd thought that was the proper way to force synchronicity when inside an async context. I'll try switching everything to await (though I seem to remember having issues with this weeks ago, as that was the first route I tried before discovering block_on - will circle back if so).
Re. what's actually happening - thanks for the explanation; that's actually really helpful for understanding! And presumably, this is implementation-dependent - i.e. this deadlock only happens in an async context, and in a synchronous context parking the thread works fine.

block_on can't be used inside an async context???

Nope, since Rust async usually multiplexes many individual futures on a single thread. An executor usually polls all until not ready, registers in some thing that can keep track cheaply (like epoll), and then waits on said thing to know when any of the those futures are ready again. If the thread is parked, it can't do that.

this deadlock only happens in an async context, and in a synchronous context parking the thread works fine.

The reqwest::blocking client actually spawns a thread to run all of its futures in, so that blocking the current thread doesn't block the runtime thread. So, sometimes the stuff will be ready by the time it hits block_on, and there's no problem. But since networking, timers and scheduling aren't deterministic, sometimes it won't be ready yet, and then you'll experience your deadlock. If you're "lucky", the deadlock always happens and is thus easy to find.

Ahhh that makes way more sense now! So I tried switching to await and got told that this is only available inside an async function. From my understanding, this means that the async would need to bubble all the way up my stack until basically everything is async (which would match what you already said - that my main function is async). I don't actually use any multithreading and would love everything to be synchronous for simplicity - it seems like the right move here would be to go the other way and figure out a way to make my main function not require tokio, correct?

Just tried to remove the tokio instantiation, and this was the error I'd seen initially:
thread 'main' panicked at 'there is no reactor running, must be called from the context of a Tokio 1.x runtime', /home/rust/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.1.1/src/runtime/context.rs:18:26
stack backtrace:
   0: rust_begin_unwind
             at ./rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:493:5
   1: core::panicking::panic_fmt
             at ./rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/panicking.rs:92:14
   2: core::option::expect_failed
             at ./rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/option.rs:1260:5
   3: std::thread::local::LocalKey<T>::with
   4: tokio::io::poll_evented::PollEvented<E>::new
   5: tokio::net::tcp::stream::TcpStream::new
   6: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
   7: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
   8: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
   9: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
  10: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
  11: <tonic::transport::service::reconnect::Reconnect<M,Target> as tower_service::Service<Request>>::poll_ready
  12: <tower::util::either::Either<A,B> as tower_service::Service<Request>>::poll_ready
  13: <tower::util::boxed::sync::Boxed<S> as tower_service::Service<Request>>::poll_ready
  14: <tonic::transport::service::connection::Connection as tower_service::Service<http::request::Request<tonic::body::BoxBody>>>::poll_ready
  15: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
  16: std::thread::local::LocalKey<T>::with
  17: futures_executor::local_pool::block_on
  18: kurtosis_rust_lib::execution::test_suite_executor::TestSuiteExecutor::run
  19: testsuite::main

I did a bunch of reading and think I understand sync/async/block_on/.await a little better. Does this mean that, because tower is involved with tonic, there's no way to get around having the tokio runtime running?

Tower itself doesn't really need Tokio. If you're using Tonic, there isn't a good way to make it all blocking. Especially if you're making a server, it's probably easiest/best to just make it all async. Otherwise, you usually need a new thread per request.

Ah sorry, this is actually for a client (which is why multithreading is way less important). That's the bit that has me sorta confused - why I need an async runtime at all for a client that's really just executing a bunch of sequential calls to the server.

Just found the tokio Discord - will move the discussion there, since that seems to be a better spot for it at this point: https://discord.com/channels/500028886025895936/628706823104626710/819665340362653727

Closing the loop here, for posterity - the problem was indeed what @seanmonstar said. Having futures::executors::block_on, mixed in with #[tokio::main] on my main function, was causing intermittent deadlocks. I didn't want to have the async contagion spread all the way up my code, so I fixed this by creating a Tokio runtime via Runtime::new() as close to the async calls as possible, and using runtime.block_on() to force synchronicity on async functions.


Change default type ramp to be consistent with Uber move theme

Hi all!
There's a few small PRs I want to open to help sync type styles with what designers currently use. The first step is to get both the internal and external type ramps consistent with each other.
This way we can tweak type styles without any negative side effects to the OS version of baseui and vice versa. In addition, fixes #226 so the metrics of the type we use match up better.
I suppose this is technically a breaking change...but I'd rather rip the bandaid off sooner so we can keep things in sync.
Fixed Issues?
#226
License
MIT

according to versioning policy css change does not require a major bump

according to versioning policy css change does not require a major bump
also, tests are failing on a jest snapshot expecting the old font value. you'll need to run the command below to update snapshots and commit the changes
yarn test -u

sounds good! didn't know we had a versioning policy, thanks for the link

maybe I am missing something here, but shouldn't we remove the font overrides from the move theme then? @nguyensomniac @chasestarr

good point. will open a separate PR!


Compatibility with Dask

Originally reported by @stsievert in #19:
I can run a Scikit-learn model selection search, but am having a difficult time running a distributed Dask-ML model selection search.
from dask.distributed import Client
from dask_ml.model_selection import HyperbandSearchCV
if __name__ == "__main__":
    # X, y, model are as above
    client = Client()
    search = IncrementalSearchCV(model2, params, max_iter=5)
    with pytest.warns(DataConversionWarning):
        search.fit(X, y)  # fails on this line

When I run this code, I get several errors error:

"TypeError: Expected float32 passed to parameter 'b' of op 'MatMul', got <tf.Variable 'dense_1_2/kernel:0' shape=(512, 10) dtype=float32> of type 'ResourceVariable' instead. Error: 'NoneType' object is not iterable" at tensorflow/python/framework/op_def_library.py", line 475, in _apply_op_helper
TypeError: 'NoneType' object is not iterable at tensorflow/python/framework/func_graph.py", line 418, in inner_cm
DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). at sklearn/utils/validation.py:73:

Here's the full output:

$  python _scikeras_bug.py
...
/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/sklearn/utils/validation.py:73: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
  return f(**kwargs)
/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/sklearn/utils/validation.py:73: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
  return f(**kwargs)
/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/sklearn/utils/validation.py:73: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
  return f(**kwargs)
/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/sklearn/utils/validation.py:73: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
  return f(**kwargs)
2020-07-15 15:07:29.807015: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2020-07-15 15:07:29.813243: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2020-07-15 15:07:29.818382: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2020-07-15 15:07:29.819346: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x7f8a7c1f1fe0 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-07-15 15:07:29.819367: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
2020-07-15 15:07:29.826941: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x7f8b0b201b60 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-07-15 15:07:29.826962: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
2020-07-15 15:07:29.837069: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x7fdc87b75290 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-07-15 15:07:29.837096: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/sklearn/utils/validation.py:73: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
  return f(**kwargs)
2020-07-15 15:07:29.916084: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
distributed.utils - ERROR - 'NoneType' object is not iterable
Traceback (most recent call last):
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/distributed/utils.py", line 656, in log_errors
    yield
  File "/Users/scott/Developer/stsievert/dask-ml/dask_ml/model_selection/_incremental.py", line 103, in _partial_fit
    model.partial_fit(X, y, **(fit_params or {}))
  File "/Users/scott/Developer/stsievert/scikeras/scikeras/wrappers.py", line 547, in partial_fit
    return self.fit(
  File "/Users/scott/Developer/stsievert/scikeras/scikeras/wrappers.py", line 511, in fit
    self.model_ = self._build_keras_model(
  File "/Users/scott/Developer/stsievert/scikeras/scikeras/wrappers.py", line 304, in _build_keras_model
    model = final_build_fn(**build_args)
  File "_scikeras_bug.py", line 36, in _keras_build_fn
    model = Sequential(layers)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/training/tracking/base.py", line 456, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/keras/engine/sequential.py", line 129, in __init__
    self.add(layer)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/training/tracking/base.py", line 456, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/keras/engine/sequential.py", line 213, in add
    output_tensor = layer(self.outputs[0])
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/keras/engine/base_layer.py", line 960, in __call__
    self._set_inputs(cast_inputs, outputs)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/contextlib.py", line 120, in __exit__
    next(self.gen)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/framework/func_graph.py", line 418, in inner_cm
    for fn in self._scope_exit_callbacks:
TypeError: 'NoneType' object is not iterable
distributed.utils - ERROR - 'NoneType' object is not iterable
Traceback (most recent call last):
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/distributed/utils.py", line 656, in log_errors
    yield
  File "/Users/scott/Developer/stsievert/dask-ml/dask_ml/model_selection/_incremental.py", line 103, in _partial_fit
    model.partial_fit(X, y, **(fit_params or {}))
  File "/Users/scott/Developer/stsievert/scikeras/scikeras/wrappers.py", line 547, in partial_fit
    return self.fit(
  File "/Users/scott/Developer/stsievert/scikeras/scikeras/wrappers.py", line 511, in fit
    self.model_ = self._build_keras_model(
  File "/Users/scott/Developer/stsievert/scikeras/scikeras/wrappers.py", line 304, in _build_keras_model
    model = final_build_fn(**build_args)
  File "_scikeras_bug.py", line 36, in _keras_build_fn
    model = Sequential(layers)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/training/tracking/base.py", line 456, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/keras/engine/sequential.py", line 129, in __init__
    self.add(layer)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/training/tracking/base.py", line 456, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/keras/engine/sequential.py", line 213, in add
    output_tensor = layer(self.outputs[0])
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/keras/engine/base_layer.py", line 960, in __call__
    self._set_inputs(cast_inputs, outputs)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/contextlib.py", line 120, in __exit__
    next(self.gen)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/framework/func_graph.py", line 418, in inner_cm
    for fn in self._scope_exit_callbacks:
TypeError: 'NoneType' object is not iterable
2020-07-15 15:07:29.932341: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x7fb0b125cc00 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-07-15 15:07:29.932392: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
distributed.worker - WARNING -  Compute Failed
Function:  execute_task
args:      ((<function _partial_fit at 0x14b23d550>, (KerasClassifier(
        build_fn=<function _keras_build_fn at 0x14b465160>
        lr=0.0018805049416974935
), {'model_id': 2, 'params': {'lr': 0.0018805049416974935}, 'partial_fit_calls': 0}), array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), array([4, 0, 2, 1, 3, 8, 5, 0, 3, 1, 2, 7, 9, 1, 3, 4, 7, 7, 1, 8, 6, 3,
       0, 9, 9, 4, 4, 5, 9, 0, 7, 6, 7, 6, 0, 0, 6, 8, 6, 3, 1, 9, 8, 1,
       7, 5, 3, 8, 6, 4, 4, 9, 4, 2, 9, 9, 2, 0, 4, 0, 7, 1, 3, 7, 1, 1,
       6, 3, 1, 2, 8, 6, 5, 2, 4, 7, 9, 9, 0, 8], dtype=uint8), (<class 'dict'>, [])))
kwargs:    {}
Exception: TypeError("'NoneType' object is not iterable")

distributed.utils - ERROR - Expected float32 passed to parameter 'b' of op 'MatMul', got <tf.Variable 'dense_1_2/kernel:0' shape=(512, 10) dtype=float32> of type 'ResourceVariable' instead. Error: 'NoneType' object is not iterable
Traceback (most recent call last):
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/framework/op_def_library.py", line 465, in _apply_op_helper
    values = ops.convert_to_tensor(
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/framework/ops.py", line 1341, in convert_to_tensor
    ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/ops/resource_variable_ops.py", line 1825, in _dense_var_to_tensor
    return var._dense_var_to_tensor(dtype=dtype, name=name, as_ref=as_ref)  # pylint: disable=protected-access
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/ops/resource_variable_ops.py", line 1242, in _dense_var_to_tensor
    return self.value()
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/ops/resource_variable_ops.py", line 550, in value
    return self._read_variable_op()
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/ops/resource_variable_ops.py", line 645, in _read_variable_op
    result = read_and_set_handle()
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/ops/resource_variable_ops.py", line 635, in read_and_set_handle
    result = gen_resource_variable_ops.read_variable_op(self._handle,
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/ops/gen_resource_variable_ops.py", line 482, in read_variable_op
    _, _, _op, _outputs = _op_def_library._apply_op_helper(
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/framework/op_def_library.py", line 759, in _apply_op_helper
    return output_structure, op_def.is_stateful, op, outputs
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/contextlib.py", line 120, in __exit__
    next(self.gen)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/framework/func_graph.py", line 418, in inner_cm
    for fn in self._scope_exit_callbacks:
TypeError: 'NoneType' object is not iterable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/distributed/utils.py", line 656, in log_errors
    yield
  File "/Users/scott/Developer/stsievert/dask-ml/dask_ml/model_selection/_incremental.py", line 103, in _partial_fit
    model.partial_fit(X, y, **(fit_params or {}))
  File "/Users/scott/Developer/stsievert/scikeras/scikeras/wrappers.py", line 547, in partial_fit
    return selTraceback (most recent call last):
  File "_scikeras_bug.py", line 65, in <module>
    search.fit(X, y)  # fails on this line
  File "/Users/scott/Developer/stsievert/dask-ml/dask_ml/model_selection/_incremental.py", line 1006, in fit
f.fit(
  File "/Users/scott/Developer/stsievert/scikeras/scikeras/wrappers.py", line 511, in fit
    self.model_ = self._build_keras_model(
  File "/Users/scott/Developer/stsievert/scikeras/scikeras/wrappers.py", line 304, in _build_keras_model
    model = final_build_fn(**build_args)
  File "_scikeras_bug.py", line 36, in _keras_build_fn
    model = Sequential(layers)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/training/tracking/base.py", line 456, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/keras/engine/sequential.py", line 129, in __init__
    self.add(layer)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/training/tracking/base.py", line 456, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensor    return super(IncrementalSearchCV, self).fit(X, y=y, **fit_params)
  File "/Users/scott/Developer/stsievert/dask-ml/dask_ml/model_selection/_incremental.py", line 695, in fit
    return client.sync(self._fit, X, y, **fit_params)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/distributed/client.py", line 831, in sync
flow/python/keras/engine/sequential.py", line 213, in add
    output_tensor = layer(self.outputs[0])
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/keras/engine/base_layer.py", line 922, in __call__
    outputs = call_fn(cast_inputs, *args, **kwargs)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/keras/layers/core.py", line 1194, in call
    outputs = gen_math_ops.mat_mul(inputs, self.kernel)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/ops/gen_math_ops.py", line 5585, in mat_mul
    _, _, _op, _outputs = _op_def_library._apply_op_helper(
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/framework/op_def_library.py", line 475, in _apply_op_helper
    raise TypeError(
TypeError: Expected float32 passed to parameter 'b' of op 'MatMul', got <tf.Variable 'dense_1_2/kernel:0' shape=(512, 10) dtype=float32> of type 'ResourceVariable' instead. Error: 'NoneType' object is not iterable
    return sync(
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/distributed/utils.py", line 339, in sync
    raise exc.with_traceback(tb)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/distributed/utils.py", line 323, in f
    result[0] = yield future
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tornado/gen.py", line 735, in run
    value = future.result()
  File "/Users/scott/Developer/stsievert/dask-ml/dask_ml/model_selection/_incremental.py", line 641, in _fit
    results = await fit(
  File "/Users/scott/Developer/stsievert/dask-ml/dask_ml/model_selection/_incremental.py", line 457, in fit
    return await _fit(
  File "/Users/scott/Developer/stsievert/dask-ml/dask_ml/model_selection/_incremental.py", line 253, in _fit
    metas = await client.gather(new_scores)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/distributed/client.py", line 1841, in _gather
    raise exception.with_traceback(traceback)
  File "/Users/scott/Developer/stsievert/dask-ml/dask_ml/model_selection/_incremental.py", line 103, in _partial_fit
    model.partial_fit(X, y, **(fit_params or {}))
  File "/Users/scott/Developer/stsievert/scikeras/scikeras/wrappers.py", line 547, in partial_fit
    return self.fit(
  File "/Users/scott/Developer/stsievert/scikeras/scikeras/wrappers.py", line 511, in fit
    self.model_ = self._build_keras_model(
  File "/Users/scott/Developer/stsievert/scikeras/scikeras/wrappers.py", line 304, in _build_keras_model
    model = final_build_fn(**build_args)
  File "_scikeras_bug.py", line 36, in _keras_build_fn
    model = Sequential(layers)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/training/tracking/base.py", line 456, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/keras/engine/sequential.py", line 129, in __init__
    self.add(layer)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/training/tracking/base.py", line 456, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/keras/engine/sequential.py", line 213, in add
    output_tensor = layer(self.outputs[0])
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/keras/engine/base_layer.py", line 960, in __call__
    self._set_inputs(cast_inputs, outputs)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/contextlib.py", line 120, in __exit__
    next(self.gen)
  File "/Users/scott/anaconda3/envs/dask-ml-test/lib/python3.8/site-packages/tensorflow/python/framework/func_graph.py", line 418, in inner_cm
    for fn in self._scope_exit_callbacks:
TypeError: 'NoneType' object is not iterable

Here's a reproducible example:

import numpy as np
import pytest
import pickle
from typing import Tuple
from sklearn.exceptions import DataConversionWarning
from dask.distributed import Client

import tensorflow as tf
from scikeras.wrappers import KerasClassifier
from tensorflow.keras.datasets import mnist as keras_mnist
from tensorflow.keras.layers import Activation, Dense, Dropout
from tensorflow.keras.models import Sequential
from tensorflow.keras.utils import to_categorical

from sklearn.model_selection import RandomizedSearchCV
from dask_ml.model_selection import IncrementalSearchCV
from scipy.stats import loguniform

def mnist() -> Tuple[np.ndarray, np.ndarray]:
    (X_train, y_train), _ = keras_mnist.load_data()
    X_train = X_train[:100]
    y_train = y_train[:100]
    X_train = X_train.reshape(X_train.shape[0], 784)
    X_train = X_train.astype("float32")
    X_train /= 255
    Y_train = to_categorical(y_train, 10)
    return X_train, y_train

def _keras_build_fn(lr=0.01):
    layers = [
        Dense(512, input_shape=(784,), activation="relu"),
        Dense(10, input_shape=(512,), activation="softmax"),
    ]
    model = Sequential(layers)

    opt = tf.keras.optimizers.SGD(learning_rate=lr)
    model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])
    return model

if __name__ == "__main__":
    X, y = mnist()
    assert X.ndim == 2 and X.shape[-1] == 784
    assert y.ndim == 1 and len(X) == len(y)
    assert isinstance(X, np.ndarray) and isinstance(y, np.ndarray)

    model = KerasClassifier(build_fn=_keras_build_fn, lr=0.1)
    params = {"lr": loguniform(1e-3, 1e-1)}
    model2 = pickle.loads(pickle.dumps(model))

    with pytest.warns(DataConversionWarning):
        m = model.partial_fit(X, y)
    assert m is model

    search = RandomizedSearchCV(model, params, n_iter=3)
    with pytest.warns(DataConversionWarning):
        search.fit(X, y, epochs=2)
    assert search.best_score_ >= 0

    client = Client()
    search = IncrementalSearchCV(model2, params, max_iter=5)
    with pytest.warns(DataConversionWarning):
        search.fit(X, y)  # fails on this line
    assert search.best_score_ >= 0

Initial investigation, working directly off of the tests in the corresponding dask PR (dask/dask-ml/issues/696)

"TypeError: Expected float32 passed to parameter 'b' of op 'MatMul', got <tf.Variable 'dense_1_2/kernel:0' shape=(512, 10) dtype=float32> of type 'ResourceVariable' instead. Error: 'NoneType' object is not iterable" at tensorflow/python/framework/op_def_library.py", line 475, in _apply_op_helper
TypeError: 'NoneType' object is not iterable at tensorflow/python/framework/func_graph.py", line 418, in inner_cm
DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). at sklearn/utils/validation.py:73:

I tested this right now, by cloning your dask branch actually.
I got two types of errors, with no clear reason as to why the alternate.
The first error was at:
model = Sequential(layers)

TypeError: 'NoneType' object is not iterable

Strangely, I could solve this by just doing:
try:
    model = Sequential(layers)
except TypeError:
    model = Sequential(layers)

This is very strange and I honestly have no idea what might cause this! It might be worth asking in TF.
The second error was:
File "/home/adrian/code/dask-ml/venv/lib/python3.7/site-packages/distributed/utils_test.py", line 954, in test_func
  coro, timeout=timeout * 2 if timeout else timeout
File "/home/adrian/code/dask-ml/venv/lib/python3.7/site-packages/tornado/ioloop.py", line 532, in run_sync
  return future_cell[0].result()
File "/home/adrian/code/dask-ml/venv/lib/python3.7/site-packages/distributed/utils_test.py", line 912, in coro
  result = await future
File "/usr/lib/python3.7/asyncio/tasks.py", line 449, in wait_for
  raise futures.TimeoutError()
concurrent.futures._base.TimeoutError

I also am not sure what could cause this, but at least it seems like a more reasonable error.

@stsievert I just added the ability to use ScikitLearn's random_state parameter in #27 . With this and your work in #17 I think there is enough to make a release so that you can use in in dask/dask-ml#699. Happy to help hammer out this, #18 or #22, just let me know what's still needed/where I can help!

This looks good to me. #18 would be nice to have but it's not close to blocking.

This looks good to me.

So you were able to resolve out this issue (#24) on your side?

This still isn't resolved for me; I'm getting some non-deterministic behavior. The example below either raises "TypeError: 'NoneType' object is not iterable" or "RuntimeError: dictionary changed size during iteration."

Example code:
from dask.distributed import Client
from scipy.stats import loguniform
from sklearn.datasets import make_regression

import tensorflow as tf
from tensorflow.keras.datasets import mnist as keras_mnist
from tensorflow.keras.layers import Dense
from tensorflow.keras.models import Sequential
from tensorflow.keras.utils import to_categorical
from scikeras.wrappers import KerasClassifier

from dask_ml.model_selection import IncrementalSearchCV
from sklearn.model_selection import RandomizedSearchCV

def mnist():
    (X_train, y_train), _ = keras_mnist.load_data()
    X_train = X_train[:100]
    y_train = y_train[:100]
    X_train = X_train.reshape(X_train.shape[0], 784)
    X_train = X_train.astype("float32")
    X_train /= 255
    Y_train = to_categorical(y_train, 10)
    return X_train, y_train

def _keras_build_fn(lr=0.01):
    layers = [
        Dense(512, input_shape=(784,), activation="relu"),
        Dense(10, input_shape=(512,), activation="softmax"),
    ]
    # See https://github.com/adriangb/scikeras/issues/24
    try:
        model = Sequential(layers)
    except (TypeError, RuntimeError):
        model = Sequential(layers)

    opt = tf.keras.optimizers.SGD(learning_rate=lr)
    model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])
    return model

if __name__ == "__main__":
    c = Client()

    X, y = mnist()
    model = KerasClassifier(build_fn=_keras_build_fn, epochs=1, lr=0.1)
    params = {"lr": loguniform(1e-3, 1e-1)}

    search = IncrementalSearchCV(model, params, max_iter=2, decay_rate=None)

    ## example works if below is uncommented
    # search = RandomizedSearchCV(model, params, n_iter=3)

    search.fit(X, y, epochs=1, n_jobs=-1)
    assert search.best_score_ >= 0

I need to do some more investigation.

Hmm yeah I haven't dived very deep, but it's strange that the behavior varies run to run and that that try:except block has any effect. Let me know what you find/if you want me to look into anything.

Hi together,
I am also working on scikeras and dask-ml.
I want to tune a Keras model with HyperbandSearchCV on a dask backend,
I run the following code with the current master of scikeras and dask-ml

Code:
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, Flatten
from scikeras.wrappers import KerasRegressor

import numpy as np

import dask_ml.model_selection as dcv
from dask.distributed import Client

dask_client = Client('localhost:8786', timeout=10)

def model_building_function(X, n_outputs_, hidden_layer_sizes, activation_func):
    """Dynamically build regressor."""

    model = Sequential()
    model.add(Flatten(input_shape=X.shape[1:]))
    for size in hidden_layer_sizes:
        model.add(Dense(size, activation=activation_func))
    model.add(Dense(n_outputs_))
    model.compile("adam", loss="mean_squared_error")
    return model

class estimator_class(KerasRegressor):
    def __init__(self, hidden_layer_sizes=None, activation_func=None):
        self.hidden_layer_sizes = hidden_layer_sizes
        self.activation_func = activation_func
        super().__init__()  # properly register kwargs and the model building function.

    def __call__(self, X, n_outputs_,
                 hidden_layer_sizes, activation_func):
        print(dict)
        model = Sequential()
        model.add(Flatten(input_shape=X.shape[1:]))
        for size in hidden_layer_sizes:
            model.add(Dense(size, activation=activation_func))
        model.add(Dense(n_outputs_))
        model.compile("adam", loss="mean_squared_error")
        return model

estimator_fn = KerasRegressor(build_fn=model_building_function, hidden_layer_sizes=[32, 32], activation_func="relu")
estimator = estimator_class(hidden_layer_sizes=[32, 32], activation_func="relu")

# generate data
X = np.arange(1.0, 5001.0).reshape((100, 50)).astype(np.float32)
y = np.arange(1.0, 101.0).reshape(100, 1).astype(np.float32)

# specify parameters and distributions to sample from
param_dist = {'hidden_layer_sizes': [[16, 16], [32, 32], [64, 64], [128, 128], [256, 256]],
              'activation_func': ['relu', 'elu']}

# run randomized search
hyperband = dcv.HyperbandSearchCV(estimator=estimator_fn,
                                      parameters=param_dist,
                                      max_iter=12,
                                      aggressiveness=3)

print("START HyperbandSearchCV")
hyperband.fit(X, y)

And I got the following error: KeyError: 'sample_weight_mode´

Full Traceback:
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "C:\Program Files\JetBrains\PyCharm 2020.1.1\plugins\python\helpers\pydev\_pydev_bundle\pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "C:\Program Files\JetBrains\PyCharm 2020.1.1\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "D:/PycharmProjects/optimization_library/test_libaries/keras+scikeras+dask_ms_hyperband.py", line 61, in <module>
    hyperband.fit(X, y)
  File "d:\pycharmprojects\optimization_library\venv_dask\src\dask-ml\dask_ml\model_selection\_incremental.py", line 706, in fit
    return client.sync(self._fit, X, y, **fit_params)
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\client.py", line 780, in sync
    self.loop, func, *args, callback_timeout=callback_timeout, **kwargs
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\utils.py", line 348, in sync
    raise exc.with_traceback(tb)
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\utils.py", line 332, in f
    result[0] = yield future
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\tornado\gen.py", line 735, in run
    value = future.result()
  File "d:\pycharmprojects\optimization_library\venv_dask\src\dask-ml\dask_ml\model_selection\_hyperband.py", line 402, in _fit
    *[SHAs[b]._fit(X, y, **fit_params) for b in _brackets_ids]
  File "d:\pycharmprojects\optimization_library\venv_dask\src\dask-ml\dask_ml\model_selection\_incremental.py", line 671, in _fit
    best_estimator = await models[best_idx]
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\client.py", line 242, in _result
    result = await self.client._gather([self])
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\client.py", line 1781, in _gather
    response = await future
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\client.py", line 1832, in _gather_remote
    response = await retry_operation(self.scheduler.gather, keys=keys)
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\utils_comm.py", line 391, in retry_operation
    operation=operation,
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\utils_comm.py", line 379, in retry
    return await coro()
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\core.py", line 757, in send_recv_from_rpc
    result = await send_recv(comm=comm, op=key, **kwargs)
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\core.py", line 540, in send_recv
    response = await comm.read(deserializers=deserializers)
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\comm\tcp.py", line 212, in read
    frames, deserialize=self.deserialize, deserializers=deserializers
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\comm\utils.py", line 75, in from_frames
    res = _from_frames()
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\comm\utils.py", line 61, in _from_frames
    frames, deserialize=deserialize, deserializers=deserializers
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\protocol\core.py", line 124, in loads
    value = _deserialize(head, fs, deserializers=deserializers)
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\protocol\serialize.py", line 268, in deserialize
    return loads(header, frames)
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\protocol\serialize.py", line 62, in pickle_loads
    return pickle.loads(b"".join(frames))
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\distributed\protocol\pickle.py", line 59, in loads
    return pickle.loads(x)
  File "d:\pycharmprojects\optimization_library\venv_dask\src\scikeras\scikeras\_utils.py", line 89, in unpack_keras_model
    **saving_utils.compile_args_from_training_config(training_config)
  File "D:\PycharmProjects\optimization_library\venv_dask\lib\site-packages\tensorflow\python\keras\saving\saving_utils.py", line 230, in compile_args_from_training_config
    sample_weight_mode = training_config['sample_weight_mode']
KeyError: 'sample_weight_mode'

Thanks for your help

And I got the following error: KeyError: 'sample_weight_mode´

I just tested this and was unable to reproduce: https://colab.research.google.com/drive/1Ma9RJII30FkX5VvXezYXyubPYRIoCgN4?authuser=1#scrollTo=yxzAH4eqzCPQ

@sim-san I'm trying to implement the same thing in Dask-ML: https://github.com/dask/dask-ml/pull/713.
@adriangb did the example work for you? If so, maybe I should look at different types build_fn.

@stsievert yes, @sim-san example worked for me. I actually just tried the example in https://github.com/adriangb/scikeras/issues/24#issue-658412638 again (notebook link) and it worked! The only thing that I could see as having changed is the Tensorflow version, since I am using tf-nightly in these notebooks. Wondering if any of the previous tests we've done were run on TF<2.1?

I'm still having some difficulty with @sim-san's example on TF 2.2.0. For me, the example in https://github.com/adriangb/scikeras/issues/24#issuecomment-666415547 fails randomly with "TypeError: 'NoneType' object is not iterable" or "RuntimeError: dictionary changed size during iteration." If it finishes successfully, it prints error messages in the meantime on deserialization ("TypeError: 'NoneType' object is not iterable").

Cleaned example
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, Flatten
from scikeras.wrappers import KerasRegressor

import numpy as np
from dask.distributed import Client, LocalCluster

import dask_ml.model_selection as dcv

def model_building_function(X, n_outputs_, hidden_layer_sizes, activation_func):
    """Dynamically build regressor."""

    model = Sequential()
    model.add(Flatten(input_shape=X.shape[1:]))
    for size in hidden_layer_sizes:
        model.add(Dense(size, activation=activation_func))
    model.add(Dense(n_outputs_))
    model.compile("adam", loss="mean_squared_error")
    return model

class Est(KerasRegressor):
    def __init__(self, hidden_layer_sizes=None, activation_func=None):
        self.hidden_layer_sizes = hidden_layer_sizes
        self.activation_func = activation_func
        super().__init__()

    def __call__(self, X, n_outputs_, hidden_layer_sizes, activation_func):
        model = model_building_function(
            X, n_outputs_, hidden_layer_sizes, activation_func
        )
        return model

if __name__ == "__main__":
    cluster = LocalCluster(processes=True, n_workers=5, threads_per_worker=1)
    #  cluster = LocalCluster(processes=False, n_workers=1, threads_per_worker=1)

    dask_client = Client(cluster)

    model = KerasRegressor(
        build_fn=model_building_function,
        hidden_layer_sizes=[32, 32],
        activation_func="relu",
    )
    #  model = KerasRegressor(build_fn=Est(), hidden_layer_sizes=[32, 32], activation_func="relu")

    # generate data
    X = np.arange(1.0, 5001.0).reshape((100, 50)).astype(np.float32)
    y = np.arange(1.0, 101.0).reshape(100, 1).astype(np.float32)

    # specify parameters and distributions to sample from
    param_dist = {
        "hidden_layer_sizes": [[16, 16], [32, 32], [64, 64], [128, 128], [256, 256]],
        "activation_func": ["relu", "elu"],
    }

    hyperband = dcv.HyperbandSearchCV(model, param_dist, max_iter=12)

    print("START HyperbandSearchCV")
    hyperband.fit(X, y)
    print("best score =", hyperband.best_score_)
    assert hasattr(hyperband, "best_score_")

I'm on TF 2.2.0, SciKeras master.

Can you test with tf-nightly?

Yup, it works on tf-nightly. The example in https://github.com/adriangb/scikeras/issues/24#issuecomment-666480764 always finishes, even when I use threads_per_worker=2. I get a repeated warning:

Repeated warning:

WARNING:tensorflow:5 out of the last 13 calls to <function Model.make_train_function..train_function at 0x143577b80> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/tutorials/customization/performance#python_or_tensor_args and https://www.tensorflow.org/api_docs/python/tf/function for  more details.

tf-nightly is v2.4.0. I've also tested on TF v2.3.0. I get the same behavior: it always works (for my runs) and I get the same repeated warning as above.

Interesting. To me, this confirms that the issues stem from some bug or middle-of-a-refactor issue within TF. Same for the warnings.
As much as I'd like to track down the root cause of these issues or warnings, I feel that it would be better if we can come up with a reproducible example that does not depend on SciKeras or Dask so that we can open an issue on the TF repo and have that team triage the issue.
Separately, maybe you can continue to work on the Dask docs @stsievert but state that the examples are only compatible with TF>=2.3.0? Even if we found the root cause, I don't see how a fix would be backported to TF<2.3.0.

Separately, maybe you can continue to work on the Dask docs @stsievert but state that the examples are only compatible with TF>=2.3.0?

Yup, that's what I've done. I've detailed the install directions.
IIRC, SciKeras v0.1.8 needs to be released to incorporate https://github.com/adriangb/scikeras/pull/17. Is that accurate? That's what I have in https://github.com/dask/dask-ml/pull/713.

Awesome! Yes, I will put out a release today or tomorrow that includes #17.

v0.1.8 released (PyPi link), closing this for now.

I think this is closed permanently. I'm not seeing any other improvements to make. I suppose you could specify tensorflow>=2.3.0 in your requirements.txt, but that's about it.

You're probably right. I thought about that but as far as SciKeras is concerned there is no issue with v2.2.0, so I thought it best to leave as is. Once you get the Dask part merged, I'll add a section to the Scikeras docs referencing those docs where I'll also specify the version req.

I thought about that but as far as SciKeras is concerned there is no issue with v2.2.0, so I thought it best to leave as is.

I reached the same conclusion. I only mentioned it as "this is all I can see to help with Dask-ML."


GetYahooStockCode method do not return expected value

Hello,
The following method do not return correct values except for US, UK & australian market (ok, the most important ones ;) )
public string GetYahooStockCode(string exchange, string code)
		{
			switch (exchange)
			{
				case "ASX":
					return $"{code}.AX";
				default:
					return code;
			}
		}

The complete list of suffix is available on http://finance.yahoo.com/exchanges
Maybe an enum of MarketExchange can make the use of the API easier ?

Thats great! I couldn't find a list of Yahoo suffixes when I first wrote it.
Are you able to get a list of exchange abbreviations so we have something to map the suffixes to?

I refactored the GetYahooStockCode method to make it easier to add exchanges/suffixes.
You can add them in the _exchanges dictionary in YahooExchangeHelper.cs.

I have added all the exchanges from http://www.wikinvest.com/wiki/List_of_Stock_Exchanges
That doesn't cover everything in the list from http://finance.yahoo.com/exchanges but I can't find the others.
Feel free to add a pull request if you find them.

That was fast !
Thanks a lot : i'll test that in coming days :)


Compiler crash when calling super with not enough arguments

http://carc.in/#/r/85c
The above testcase is the smallest I can get to make the compiler crash. What I would expect in this case is the compiler to tell me that I'm missing an argument in line 22.
Note that when I remove the override 'send' method the compiler will not crash and give me the expected error instead.

Still crashes with 0.7.7, with a different (and smaller) error http://carc.in/#/r/e9a