0

I'm pretty new in Java. I would like to initiate an array using Nd4j library INDArray x = new Nd4j.linspace(0, 1, 100);, doing something like x = np.linspace(0, 1, 100) in Python. And I ran into an error

java: cannot find symbol

symbol: class linspace location: class

org.nd4j.linalg.factory.Nd4j

Although my Nd4j was well installed adding the following in pom.xml, and my IDE IntelliJ can detect ND4j class.

    <dependency>
        <groupId>org.nd4j</groupId>
        <artifactId>nd4j-api</artifactId>
        <version>1.0.0-M2</version>
    </dependency>

Am I missing or misunderstood anything? Thanks for your kind help

Zézouille
  • 503
  • 6
  • 21
  • 2
    You're trying to create a **class** called `org.nd4j.linalg.factory.Nd4j.linspace`, which does not exist. Maybe `linspace` is a **method**, if so, remove `new`. – Mark Rotteveel Jul 13 '22 at 05:58
  • For reference your method call appears correct: https://javadoc.io/static/org.nd4j/nd4j-api/1.0.0-M2/org/nd4j/linalg/factory/Nd4j.html#linspace-long-long-long- So the issue is likely to be that your API/library is not setup correctly. – sorifiend Jul 13 '22 at 06:27
  • @sorifiend The OP is using `new`, so they're calling a constructor, not a method, and that what you show is a method. – Mark Rotteveel Jul 13 '22 at 06:39

2 Answers2

2

The problem is:

INDArray x = new Nd4j.linspace(0, 1, 100);

Because you use new, Java tries to create a class called Nd4j.linspace, which does not exist (as indicated by the "cannot find symbol, symbol: class linspace"). The class Nd4j does have a method linspace. To fix this, remove new so you call the method:

INDArray x = Nd4j.linspace(0, 1, 100);
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • 1
    Yes this is correct. OP: please flag this as the correct more concise answer. I will leave my answer up for anyone else wondering about general dependencies. Don't depend directly on api and never create INDArray objects with new. Use the Nd4j static methods instead. This will allow your code to remain backend independent. – Adam Gibson Jul 13 '22 at 07:09
0

Edit: Apologies. Thanks to the commenter down below. That error upon first glance looked like the standard error you get when the IDE only shows part of the error. That's very common when you are missing a backend.

In the context of a compilation error ensure you still have the backend. You don't need to depend on nd4j-api directly. It will be pulled in as a transitive dependency and wont' work without a backend anyways.

For the IDE, just make sure after declaring the correct dependencies (please see below answer for that) then refresh your maven context to ensure that the IDE has the correct information. Also ensure that you give the IDE time to download the correct dependencies.

Note also with the IDE it may still be out of sync so you may also test it independently on command line. When you do this you can just run:

mvn clean install -DskipTests

If your project compiles, then your IDE is the problem. That may mean you need to restart it or invalidate your IDE's cache.

On your correct dependencies:

You need more than just api. You need to pick a backend. A backend allows you to either use cpu or gpu depending on your use case.

Note that nd4j-api is just the layer for which you access lower level functionality provided by a specific implementation(eg: a backend)

Most of the time this is going to be nd4j-native-platform. This will allow you to use a cpu backend.

In concrete terms this will be:

    <dependency>
        <groupId>org.nd4j</groupId>
        <artifactId>nd4j-native-platform</artifactId>
        <version>1.0.0-M2</version>
    </dependency>

Note that when you specify nd4j-native-platform it will provide everything you need but will require a bit of time to download.

This artifact pre declares a set of dependencies for every operating system that nd4j supports. When running maven, you may prevent this by adding a JVM property:

mvn -Djavacpp.platform="$YOUR_PLATFORM" clean package

You should be able to also pre specify this in your pom's properties like:

<properties>
<javacpp.platform>$YOUR_PLATFORM</javacpp.platform>
</properties>

$YOUR_PLATFORM can usually be one of: linux-x86_64, windows-x86_64, macosx-x86_64 These are maven classifiers. You can see the comprehensive list for a particular version here: https://repo1.maven.org/maven2/org/nd4j/nd4j-native/1.0.0-M2/

Note that 1.0.0-M2 is the current version but may change so always specify the newest version if you want a version for a specific platform.

Adam Gibson
  • 3,055
  • 1
  • 10
  • 12
  • _"You didn't post the full stack trace which makes it harder to help you."_ The OP posted a **compilation error**. Your answers seems to be a general troubleshooting reply instead of addressing the specifics of the question. – Mark Rotteveel Jul 13 '22 at 06:40
  • Ah sorry you're right. I'll update my answer there but it still provides the answer the user needs. The only dependency you need for the library here is nd4j-native. – Adam Gibson Jul 13 '22 at 06:56
  • Hi, I've updated the post. Sorry again. I just glanced at it and started responding. I added some tips relevant to the question and linked that to the previous answer I gave. The answer I gave still holds true. The dependency they're using isn't the correct one to get full functionality. – Adam Gibson Jul 13 '22 at 06:59
  • Your answer still doesn't address the specific problem of the question though. You might be addressing the next problem the OP is going to have after they fix their current problem. – Mark Rotteveel Jul 13 '22 at 07:04
  • Sure no problem. Sorry for the confusion. Thanks to Mark for pointing out the problem and providing a great concise answer. – Adam Gibson Jul 13 '22 at 07:36