jenetics / jenetics

Jenetics - Genetic Algorithm, Genetic Programming, Grammatical Evolution, Evolutionary Algorithm, and Multi-objective Optimization
https://jenetics.io
Apache License 2.0
852 stars 153 forks source link

Using Jenetics with GraalVM #538

Open jenetics opened 5 years ago

jenetics commented 5 years ago

Make some GA example with Jenetics running with GraalVM and describe how to do so.

xtagon commented 5 months ago

I have been running some of the provided examples as well as custom experiments on GraalVM for version 8.0.0 of Jenetics and haven't run into any problems yet 👍

jenetics commented 5 months ago

Great! I haven't had time jet to tryout GraalVM myself. It would be amazing if you could post a short description what you did and how you ran the examples. :)

Regards Franz

xtagon commented 5 months ago

In short:

Java isn't my primary language, so I'm sure there's an easier way than by copying, but it was simple and worked.

I haven't tried any GraalVM specific behaviors yet, such as interop. But Jenetics seems to "just work" as is.

xtagon commented 5 months ago

Update: I just tried modifying GrammaticalJavaScriptEvolution.java to use GraalVM's polyglot interop instead of the nashorn engine (which isn't available in GraalVM, and potentially no longer available in other JDKs if I recall?)

This basically amounted to replacing the codec with just a String representing the script, and setting up a fitness function like so:

    @Override
    public Function<String, Double> fitness() {
        return script -> {
            final Result<Double> result = _sampling.eval(args -> {
                try (Context context = Context.create()) {
                    String source = script.isEmpty() ? "x => NaN" : "x => " + script;
                    Value function = context.eval("js", source);
                    assert function.canExecute();
                    return function.execute(args[0]).asDouble();
                }
            });
            return ERROR.apply(TreeNode.of(), result.calculated(), result.expected());
        };
    }

Note that this is just experimental and potentially unsafe because it's not using GraalVM's isolate, which is not available on the community edition.

Tested on GraalVM CE 21 with the following dependencies in pom.xml:

   <dependencies>
        <dependency>
            <groupId>io.jenetics</groupId>
            <artifactId>jenetics</artifactId>
            <version>8.0.0</version>
        </dependency>

        <dependency>
            <groupId>io.jenetics</groupId>
            <artifactId>jenetics.ext</artifactId>
            <version>8.0.0</version>
        </dependency>

        <dependency>
            <groupId>io.jenetics</groupId>
            <artifactId>jenetics.prog</artifactId>
            <version>8.0.0</version>
        </dependency>

        <dependency>
            <groupId>io.jenetics</groupId>
            <artifactId>jenetics.xml</artifactId>
            <version>8.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.graalvm.polyglot</groupId>
            <artifactId>polyglot</artifactId>
            <version>23.1.1</version>
        </dependency>

        <dependency>
            <groupId>org.graalvm.polyglot</groupId>
            <!-- Select language: js, ruby, python, java, llvm, wasm, languages-->
            <artifactId>js-community</artifactId>
            <version>23.1.1</version>
            <type>pom</type>
        </dependency>
    </dependencies>