Java AI Interface for Spring - Page 20

Java AI Interface for Spring

Here is where ideas can be collected for the skirmish AI in development

Moderators: hoijui, Moderators

User avatar
hoijui
Former Engine Dev
Posts: 4344
Joined: 22 Sep 2007, 09:51

Re: Java AI Interface for Spring

Post by hoijui »

looks like JNAs site is up again after a downtime (at least i was not able to get there for some days)

i tried the patch you suggested cranphin, on top of latest JNA SVN (17).
You might test with putting the two jars into the AI/Interfaces/Java/0.1/jlib dir (dont forget to delete the linux specific one, when going back the the default jna).
I did not compile hte windows version, if you need that, tell me, and i'll do it.
in case you want to fiddle around with the code yourself, i also attached the changed source file (no other changes then in this file).

this is the diff:

Code: Select all

240c240
<         allocateMemory(initFromNative(true));
---
>         allocateMemory(calculateSize(true));
251c251
<             size = initFromNative(false);
---
>             size = calculateSize(false);
613,647d612
< 	private static class StructureInfo {
< 		int structAlignment;
< 		int size;
< 		Map/*<String, StructureField>*/ structFields;
< 		//List (Set?) initializeFieldNames;
< 	}
< 
< 	private static Map/*<Class, StructureInfo>*/ structureInfos = new HashMap/*<Class, StructureInfo>*/();
< 
<     int initFromNative(boolean force) {
< 
< 		int myNativeSize = Structure.CALCULATE_SIZE;
< 
< 		Class myClass = this.getClass();
< 		// try to get from the cache
< 		if (structureInfos.containsKey(myClass)) {
< 			StructureInfo myInfo = (StructureInfo) structureInfos.get(myClass);
< 			myNativeSize    = myInfo.size;
< 			structAlignment = myInfo.structAlignment;
< 			structFields.putAll(myInfo.structFields);
< 		} else {
< 			myNativeSize = calculateSize(force);
< 			if (myNativeSize != Structure.CALCULATE_SIZE) {
< 				// cache the calculated values
< 				StructureInfo myInfo = new StructureInfo();
< 				myInfo.size            = myNativeSize;
< 				myInfo.structAlignment = structAlignment;
< 				myInfo.structFields    = structFields;
< 				structureInfos.put(myClass, myInfo);
< 			}
< 		}
< 
< 		return myNativeSize;
<     }
< 
659c624
<     protected int calculateSize(boolean force) {
---
>     int calculateSize(boolean force) {
831c796
<             initFromNative(true);
---
>             calculateSize(true);
it is not very nice, and laggs docu, but together with some speed comparison tests, could probably be a motivation for the JNA devs to do it ;-)

test:
It compiles and runs with the javaaispeed branch as it is now (no changes were needed). Just the performance is to be checked.

edit:
* added source file to attached zip
* added "test" paragraph
Attachments
modifiedJNA.zip
(251.13 KiB) Downloaded 34 times
cranphin
Posts: 136
Joined: 13 Jun 2005, 16:37

Re: Java AI Interface for Spring

Post by cranphin »

hoijui wrote:looks like JNAs site is up again after a downtime (at least i was not able to get there for some days)
dev.java.net was/is suffering some sort of DOS attack or similar, on top of their usually not stellar performance :)
http://www.java.net/author/sonya-barry
Look under weblogs :)
hoijui wrote:I tried the patch you suggested cranphin, on top of latest JNA SVN (17).
You might test with putting the two jars into the AI/Interfaces/Java/0.1/jlib dir (dont forget to delete the linux specific one, when going back the the default jna).

it is not very nice, and laggs docu, but together with some speed comparison tests, could probably be a motivation for the JNA devs to do it ;-)

test:
It compiles and runs with the javaaispeed branch as it is now (no changes were needed). Just the performance is to be checked.
I've already been playing around with this myself :D
I created a modified jna.jar by just replacing the class I modified (Structure.class and Structure$..).

On 'loop' tests I see good performance benefits. (And also with the -server flag).
While playing games it's a bit harder to determine, it feels better, but I need to put the profiler on it still :)
But, I ran into some things where my 'naive' implementation broke, there's things I still need to set or cache I think :)
I think it was creating EnemyDamaged events for example that throws a exception (which isn't logged, need to do something about that XD).
I only get a 'errorcode 2' :)

Ohyeah, from the TODO in jna:
"* cache structure information"
Atleast it's on their todolist now :D

Oh! And the weakmap would be a good idea, I think :)
Last edited by cranphin on 03 Oct 2009, 12:05, edited 1 time in total.
cranphin
Posts: 136
Joined: 13 Jun 2005, 16:37

Re: Java AI Interface for Spring

Post by cranphin »

"t.printStackTrace();" in OOAIFactory, where does that go to ? :D
Even if I run spring.exe from a cmd.exe, I don't see the output :)

Btw., only slightly related, I prefer log4j over Java logging :)

Ah :)
spring.exe script.txt 2> stderr.log

And the trace :) Not this is a later implementation I did, not your code (very similar though).

Code: Select all

java.lang.NullPointerException
	at com.sun.jna.Pointer.getValue(Pointer.java:388)
	at com.sun.jna.Structure.readField(Structure.java:518)
	at com.sun.jna.Structure.read(Structure.java:420)
	at com.springrts.ai.event.UnitDamagedAIEvent.<init>(UnitDamagedAIEvent.java:48)
	at com.springrts.ai.oo.OOAIFactory.handleEvent(OOAIFactory.java:128)
Last edited by cranphin on 03 Oct 2009, 12:22, edited 1 time in total.
cranphin
Posts: 136
Joined: 13 Jun 2005, 16:37

Re: Java AI Interface for Spring

Post by cranphin »

Btw., some more optimizing :)
Doesn't have as much effect as the other code, but it helps :)
It's especially the getDeclaringClass method that seems very expensive!

Code: Select all

    static Map<Class,TypeMapper>  typeMappers = new HashMap<Class,TypeMapper>() ;

    protected void setTypeMapper(TypeMapper mapper) {
        if (mapper == null) {
            Class<? extends Structure> myClass = getClass();
            if (typeMappers.containsKey(myClass)) {
                mapper = typeMappers.get(myClass);
            } else {
                mapper = determineTypeMapperInner(mapper);
                typeMappers.put(getClass(), mapper);
            }            
        }
        this.typeMapper = mapper;
        this.size = CALCULATE_SIZE;
        if (this.memory instanceof AutoAllocated) {
            this.memory = null;
        }
    }

    private TypeMapper determineTypeMapperInner(TypeMapper mapper) {
        Class declaring = getClass().getDeclaringClass();
        if (declaring != null) {
            mapper = Native.getTypeMapper(declaring);
        }
        return mapper;
    }

Code: Select all

  static Map<Class,Integer>  alignTypes = new HashMap<Class,Integer>() ;

    protected void setAlignType(int alignType) {
        if (alignType == ALIGN_DEFAULT) {
            Class<? extends Structure> myClass = getClass();
            if (alignTypes.containsKey(myClass)) {
                alignType = alignTypes.get(myClass);
            } else {
                alignType = determineAlignTypeInner(alignType);
                alignTypes.put(getClass(), alignType);
            }
        }
        this.alignType = alignType;
        this.size = CALCULATE_SIZE;
        if (this.memory instanceof AutoAllocated) {
            this.memory = null;
        }
    }

    private int determineAlignTypeInner(int alignType) {
        Class declaring = getClass().getDeclaringClass();
        if (declaring != null)
            alignType = Native.getStructureAlignment(declaring);
        if (alignType == ALIGN_DEFAULT) {
            if (Platform.isWindows())
                alignType = ALIGN_MSVC;
            else
                alignType = ALIGN_GNUC;
        }
        return alignType;
    }
cranphin
Posts: 136
Joined: 13 Jun 2005, 16:37

Re: Java AI Interface for Spring

Post by cranphin »

Hmm... think you could paste some lines of code for a function that returns a UnitDamagedAIEvent c struct ? :)
I want to make an example so it's easier to debug ;)
In Spring you get the memory given to you when spring calls the Java code I think, but a method which returns a struct pointer should have the same effect/bug I think :)
cranphin
Posts: 136
Joined: 13 Jun 2005, 16:37

Re: Java AI Interface for Spring

Post by cranphin »

Hmm. the test doesn't reproduce the problem XD
drat :)

Time to go back to remote debugging I guess :)

edit:
Ah! Ofcourse XD
I need to call it twice, to make the caching kick in, now it reproduces :D
cranphin
Posts: 136
Joined: 13 Jun 2005, 16:37

Re: Java AI Interface for Spring

Post by cranphin »

Well, found and (hopefully) fixed the 'bug', without losing significant performance it seems :)

New patch to try for the ai performance branch ? :)

It's not very clean yet, feel free to clean it up :)
Sorry for not taking your cleanup from the previous patch ;)

On a short test this seems to run well with my AI :)
performance feels faster, but hard to say since I've tweaked the AI itself too. Would be nice to see how hughs ai performs with this!! :)

SVN version for this patch is 986, but it says so in the patch too ;)

Have fun :)
Attachments
patch.txt
(7.27 KiB) Downloaded 35 times
User avatar
hoijui
Former Engine Dev
Posts: 4344
Joined: 22 Sep 2007, 09:51

Re: Java AI Interface for Spring

Post by hoijui »

wow! looks.. complicated at first glance :D
am way to tired to try to look what you really do there now.

but as it works and is faster: good work! :D
will try it tomorow.

independent from the speed improvements:
i just got to know maven, and it seems to be a nice build tool for Java projects.
Currently, each Java AI has a CMake build script (can only be used through the main spring build script) and an Ant script.
The nice thing with Maven is, that it has a nice dependency management system. currently, dependencies (jar files) are included with the Java AI Interface and the Skirmish AIs in the repository (data/jlib). Using maven, we could remove all these libs from the repo, and let them be auto-downloaded when building the Interface/AIs for the first time. The only downside i see: you have to install Maven when you want to compile spring with Java AI support (which can already be disabled through setting a simple CMake variable at configure time). of course, I could let CMake just skip Java AI support if Maven is not installed on the system.
So if we moved to Maven, we could call the maven project from CMake, and only do some simple pre and post work (eg move stuff from build to install dir), The pros and cons:
  • - Maven dependency for Java AI support when building with CMake
  • - Les comfortable to build spring with Java AI support if no Internet connection is available
  • + Java dependencies do not have to recide in the repository
  • + Only one project to maintain per AI Maven instead of CMake & Ant (though the CMake one was externalized anyway)
  • + Maven projects can be directly opened in Netbeans and Eclipse
Maven is a really small install, and then downloads all its own dependencies and the ones of the project to build from a repository.
The default Maven repository contains really a LOT of dependencies. All the ones i searched so far, i found in there, examples:
  • springframework
  • jruby
  • groovy
  • JNA
  • apache commons
  • log4j
if you want to check for the libs that you use, you can search them here:
http://www.mvnrepository.com
currently over 60'000

optionally you could still specify dependencies with a local file-path, if yours is not in any repo.

feedback please! do you see any problems?
cranphin
Posts: 136
Joined: 13 Jun 2005, 16:37

Re: Java AI Interface for Spring

Post by cranphin »

Bwaa, Illness, *die* ^_^

Anyway, yeah, Maven.., it's got it's pro's and con's :)
Pro: structured development and repositories with lots of stuff.
Cons: framework forces you to work certain ways and you're relying on the internet, and the default repo tends to be a mess sometimes, and documentation is confusing since Maven consists of many plugins :)

Maven is a love/hate thing XD

Also, you don't have to use the default maven repository, you could create your own, not sure if that's something you want tho :) or multiple repositories, I think, haven't used it in a while :)
In a company I recommend building your own repository, since it means you control everything, instead of relying on 3d party maintainers (and they sometimes break the maven repo's XD). But we're not a company ;)

One big question is how does it integrate with the whole of Spring building, if it means making it harder for people compiling spring, then mayby we don't want it :) Will the build factory or whatever it is work with it ?

But it's an interesting idea, just try it ? :)
cranphin
Posts: 136
Joined: 13 Jun 2005, 16:37

Re: Java AI Interface for Spring

Post by cranphin »

Ohyeah, about the patch, if some other people can also look at it, and mayby another ai or two be tested against it, we can post it to the jna mailing list again. I'm sure it's not code they'd want to just use, but mayby it can speed up the process of them implementing something similar :)
User avatar
hoijui
Former Engine Dev
Posts: 4344
Joined: 22 Sep 2007, 09:51

Re: Java AI Interface for Spring

Post by hoijui »

Yeah.. i was thinking about having a repository for spring, but it seems not very reasonable in hte end:
all the dependencies are in the maven repo already, so it owuld only really be for the Java part of the AI Interface and the Java AIs.
It would not be a good sulotion (if it would work at all) to use it for distributing IAs to end clients, as they would need maven and it would only work for Java AIs, plus it is not deisgned for this...
actually i found no real pro for it.

The current system and Maven support can be run in parallel, as long as hte dependencies remain in the repository. I guess it would be good to keep the dependencies of the Interface in there, but supply Maven support for AIs.
Why i started looking into maven in the first place:
A ... kind of test AI i am working on, already has about 30MB dependencies in its repo, while the rest of the repo is around 100KB.
A lot of the dependencies will likely be used by other projects (Apache Commons stuff, springframework, log4J, ...)
Using Maven, the Repository gets much smaller, plus the user (someone compiling the AI) has to download the dependencies only once, no matter how many forks we will get, or how many other AIs using the same dependencies he will compile.
I already did a Maven Project for the Java Interface, and found out that it is really easy to call Ant form it, which is what i do for generating the sources, it now works like:
CMake creates GNU Makefiles
GNU Makefiles call Maven
Maven Calls Ant
Ant calls AWK to generate sources
Maven compiles the sources
was really easy to set up from what was already there, and seems to work.
cranphin
Posts: 136
Joined: 13 Jun 2005, 16:37

Re: Java AI Interface for Spring

Post by cranphin »

Oh, and a small thing I'm sure you've noticed too by now ^_^
There seems to be a significant influx of people writing Java AI's, so great job for starting this idea in the first place, it was genius :D
User avatar
hoijui
Former Engine Dev
Posts: 4344
Joined: 22 Sep 2007, 09:51

Re: Java AI Interface for Spring

Post by hoijui »

sorry.. just now tried your patch.
it does not compile :D
forst of all, i had to adjust it, cause the JNA ant script uses source compatibility 1.4 (no generics, and some other things). after that, i was left with one compile error:
Looks like we use different sources of JNA. How did you get yours?
I am using the packaged source on from their website under Documents & files - src-full.zip.
You may actually use SVN? :D
cranphin
Posts: 136
Joined: 13 Jun 2005, 16:37

Re: Java AI Interface for Spring

Post by cranphin »

Hmm, soooo.. :)

The JNA Structure caching and such shows some decent improvements, but anything involving AIFloat3 it still feels very slow compared to c/c++.

Looking at profiling results, it seems part of this is for example in reflection, which is used to set values, which is bound to the JDK and very hard to fix (and if someone uses older Java versions, it will be worse :) ).

Soo, I finally got round to testing doing things a different way.
I created a c++ function like this:

Code: Select all

EXPORT(void) skirmishAiCallback_Unit_getPosArr(int teamId, int unitId, float arr[]);
This uses a JNA native mapping like this:

Code: Select all

public native void skirmishAiCallback_Unit_getPosArr(int teamId, int unitId, float[] arr);
And I run a test against this like thi, note the use if Vector3f, which is a lot nicer then AIFloat3 anyways:

Code: Select all

private static long posDirectArrTest(final AIInterface myLib) {
        final long nanoStart = System.nanoTime();
        Vector3f pos = null;
        float[] temp = new float[3];
        for (int cnt = 0; cnt < CALLS; cnt++) {
            myLib.skirmishAiCallback_Unit_getPosArr(1, 1, temp);
            pos = new Vector3f(temp[0], temp[1], temp[2]);
        }
        final long nanoEnd = System.nanoTime();

        System.out.println(pos);
        return TimeUnit.NANOSECONDS.toMillis(nanoEnd - nanoStart);
    }
When I run a similar test with AIFloat3, using native mapping and the caching patches for JNA, this takes 220ms for 40000 calls, not bad, but when I'm querying the position of 100's of units, it's too slow :)

When I run the same test as described above, using the float[] array and native mapping, it takes 22ms!!! That's a 1000% performance increase :)

So..
I suggest we drop AIFloat3, and switch to what I've described here :)
It will suck changing the awk scripts, and existing AI need to be adapted to a new interface, but this change together with native mapping should really speed up things :)

Ofcourse, artificial test, mayby I missed something, but I've got really good hopes for this :) (with native mapping! it needs native mapping :) ).
cranphin
Posts: 136
Joined: 13 Jun 2005, 16:37

Re: Java AI Interface for Spring

Post by cranphin »

hoijui wrote:sorry.. just now tried your patch.
it does not compile :D
forst of all, i had to adjust it, cause the JNA ant script uses source compatibility 1.4 (no generics, and some other things). after that, i was left with one compile error:
Looks like we use different sources of JNA. How did you get yours?
I am using the packaged source on from their website under Documents & files - src-full.zip.
You may actually use SVN? :D
I use SVN XD
And I cheat by not letting jna compile the classes, but let eclipse do it, so that means I don't have the source compatibility problem :)
Sorry :D

Hmm, any suggestion how to go around this ? :)
I'm happy to help :)
feel free to ping me on springlobby, I'll start it now :)
User avatar
hoijui
Former Engine Dev
Posts: 4344
Joined: 22 Sep 2007, 09:51

Re: Java AI Interface for Spring

Post by hoijui »

nice nice :-)
i had a chat with cranphin.
The current plan is to do the change he suggested (using float[] insteaf of AIFloat3 in native code)
User avatar
hoijui
Former Engine Dev
Posts: 4344
Joined: 22 Sep 2007, 09:51

Re: Java AI Interface for Spring

Post by hoijui »

Pushed the above mentioned to javaaispeed. There is no structure beeing used in the callback anymore now, still is used in events and commands though. I only Tested with NullJavaAI, calling Unit.getPos once(), to see if it works (does not crash).

Note ot self:
have to change getResourceMapSpotsPositions from this:
[code]
void getSpots(SAIFloat3[] spots);
[/code]
to this:
[code]
int getSpotsSize();
SAIFloat3 getSpotsAtIndex(int i);
[/code]
in the C interface. this will not only help the Java interface but make the C interface arrays-of-structs free, which can't be bad.


edit: forgot:
This will probably be slower now, as AIFloat3 still inherits from Structure, and therefore allocates native memory and calculates size and stuff. Can not yet get rid of that as it is needed for Events and Commands still.
Will work on that.
cranphin
Posts: 136
Joined: 13 Jun 2005, 16:37

Re: Java AI Interface for Spring

Post by cranphin »

hoijui wrote:Pushed the above mentioned to javaaispeed. There is no structure beeing used in the callback anymore now, still is used in events and commands though. I only Tested with NullJavaAI, calling Unit.getPos once(), to see if it works (does not crash).
Awesome! :)
hoijui wrote:edit: forgot:
This will probably be slower now, as AIFloat3 still inherits from Structure, and therefore allocates native memory and calculates size and stuff. Can not yet get rid of that as it is needed for Events and Commands still.
Will work on that.
Ahh., yes, that would make a pretty big difference :D
Ahwell, no rush :)
I'm tinkering with some basic things on the ai for now (like seeing why CA doesn't work well with kaik, which has to do with numbers a lot :D And appartenly CA cheats on windmills, they set their output by lua script, so you can't detect them based on their UnitDef :) ).

I'm realizing that a AI which supports both BA and CA and others, will probably -need- configuration files, which sucks, cause it causes bad end user experience :)
Thing I need to know from a mod, or need to be able to derive for example:
- What is the energy to metal ratio, as in, how much energy is one metal worth. Kaik assumes 45, but I think that's wrong for CA.
- What is the energy production against building cost ratio for all the energy producers (and CA doesn't tell me that for the windmills, because it works by lua 'hacking').

I'm sure there's going to be a lot more when I look more into it :)
*sigh*
*starts writing config file support* :D

Hmm, how do you determine the mod name anyways ? :)
cranphin
Posts: 136
Joined: 13 Jun 2005, 16:37

Re: Java AI Interface for Spring

Post by cranphin »

Hmm, small question btw. :)
It seems that for each UnitDef there's a MoveDef (which has a unique id).
But there seems to be only a small amount of MoveDef which have unique data.

Wouldn't it make more sense if there were fewer MoveDef instances ? :)
(So each MoveDef has a unique id, -and- has unique data).

Hope that made sense :D
Sometimes hard to explain :)

P.S.
It seems the getPathType of the MoveData does identify the unique data set, so it would seem MoveData should have a unique instance per pathType, not per UnitDef :)
User avatar
hughperkins
AI Developer
Posts: 836
Joined: 17 Oct 2006, 04:14

Re: Java AI Interface for Spring

Post by hughperkins »

Hey hoijui, quick heads up: Apache Maven. It's a build tool like ant, but it's I feel far more declarative, higher level, with very standardized project directory layouts, and very tight project files. They have a 5-minute tutorial which shows pretty much the 'look-and-feel' of it.
Post Reply

Return to “AI”