Contents¶
- Using the Julia REPL
- Running serial and parallel code
- Installing and managing packages
Introduction¶
Julia has its own way of running code and using packages. Many educational sources about Julia assume that you have this basic knowledge, which can be confusing to new users. In this lesson, we will learn these basic skills so that you can start learning more on Julia.
Preliminaries¶
This is a tutorial. To follow it:
- Download and install Julia from https://julialang.org/
- Download and install VSCode and its Julia extension. How to: https://www.julia-vscode.org/docs/dev/gettingstarted/
- Continue reading this document
The Julia REPL¶
There are several ways of opening Julia depending on your operating system and your IDE, but it is usually as simple as launching the Julia app. With VSCode, open a folder (File > Open Folder). Then, press Ctrl+Shift+P to open the command bar, and execute Julia: Start REPL. If this does not work, make sure you have the Julia extension for VSCode installed. Independently of the method you use, opening Julia results in a window with some text ending with:
julia>
You have just opened the Julia read-evaluate-print loop, or simply the Julia REPL. Congrats! You will spend most of time using the REPL, when working in Julia. The REPL is a console waiting for user input. Just as in other consoles, the string of text right before the input area (julia> in the case) is called the command prompt or simply the prompt.
The usage is as follows:
- You write some input
- press enter
- you get the output
For instance, try this
julia> 1 + 1
Hello world!¶
A "Hello world" example looks like this in Julia
julia> println("Hello, world!")
Try to run it in the REPL.
Help mode¶
Curious about what function println does? Enter into help mode to look into the documentation. This is done by typing a question mark (?) into the inut field:
julia> ?
After typing ?, the command prompt changes to help?>. It means we are in help mode. Now, we can type a function name to see its documentation.
help?> println
Package and shell modes¶
The REPL comes with two more modes, namely package and shell modes. To enter package mode type
julia> ]
Package mode is used to install and manage packages. We are going to discuss the package mode in greater detail later. To return back to normal mode press the backspace key several times.
To enter shell mode type semicolon (;)
julia> ;
The prompt should have changed to shell> indicating that we are in shell mode. Now you can type commands that you would normally do on your system command line. For instance,
shell> ls
will display the contents of the current folder in Mac or Linux. Using shell mode in Windows is not straightforward, and thus not recommended for beginners.
Running more complex code¶
Real-world Julia programs are not typed in the REPL in practice. They are written in one or more files and included in the REPL. To try this, create a new file called hello.jl, write the code of the "Hello world" example above, and save it. If you are using VSCode, you can create the file using File > New File > Julia File. Once the file is saved with the name hello.jl, execute it as follows
julia> include("hello.jl")
"hello.jl" is located in the current working directory of your Julia session. You can query the current directory with function pwd(). You can change to another directory with function cd() if needed. Also, make sure that the file extension is .jl.
The recommended way of running Julia code is using the REPL as we did. But it is also possible to run code directly from the system command line. To this end, open a terminal and call Julia followed buy the path to the file containing the code you want to execute.
$ julia hello.jl
Previous line assumes that you have Julia properly installed in the system and that is usable from the terminal. In UNIX systems (Linux and Mac), the Julia binary needs to be in one of the directories listed in the PATH environment variable. To check that Julia is properly installed, you can use
$ julia --version
If this runs without error and you see a version number, you are good to go!
$, it should be run in the terminal. Otherwise, the code is to be run in the Julia REPL.
Running parallel code¶
Since we are in a parallel computing course, let's run a parallel "hello world" example in Julia. Open a Julia REPL and write
julia> using Distributed
julia> @everywhere println("Hello, world! I am proc $(myid()) from $(nprocs())")
Here, we are using the Distributed package, which is part of the Julia standard library that provides distributed memory parallel support. The code prints the process id and the number of processes in the current Julia session.
You will provably only see output from 1 proces. We need to add more processes to run the example in parallel. This is done with the addprocs function.
julia> addprocs(3)
We have added 3 new processes, plus the old one, we have 4 processes. Run the code again.
julia> @everywhere println("Hello, world! I am proc $(myid()) from $(nprocs())")
Now, you should see output from 4 processes.
It is possible to specify the number of processes when starting Julia from the terminal with the -p argument (useful, e.g., when running in a cluster). If you launch Julia from the terminal as
$ julia -p 3
and then run
julia> @everywhere println("Hello, world! I am proc $(myid()) from $(nprocs())")
You should get output from 4 processes as before.
Installing packages¶
One of the most useful features of Julia is its package manager. It allows one to install Julia packages in a straightforward and platform independent way. To illustrate this, let us consider the following parallel "Hello world" example.
Copy the following block of code into a new file named "hello_mpi.jl"
# file hello_mpi.jl
using MPI
MPI.Init()
comm = MPI.COMM_WORLD
rank = MPI.Comm_rank(comm)
nranks = MPI.Comm_size(comm)
println("Hello world, I am rank $rank of $nranks")
As you can see from this example, one can access MPI from Julia in a clean way, without type annotations and other complexities of C/C++ code.
Now, run the file from the REPL
julia> incude("hello_mpi.jl")
It provably didn't work, right? Read the error message and note that the MPI package needs to be installed to run this code.
To install a package, we need to enter package mode. Remember that we entered into help mode by typing ?. Package mode is activated by typing ]
julia> ]
At this point, the promp should have changed to (@v1.8) pkg> indicating that we are in package mode. The text between parenthesis indicates which is the active project, i.e., where packages are going to be installed. In this case, we are working with the global project associated with our Julia installation (which is Julia 1.8 in this example, but it can be another version in your case).
To install the MPI package, type
(@v1.8) pkg> add MPI
Congrats, you have installed MPI!
.jl. This is just a way of signaling that a package is written in Julia. When using such packages, the .jl needs to be ommited. In this case, we have isntalled the MPI.jl package even though we have only typed MPI in the REPL.
MPI.jl. Note that it is not a MPI library by itself. It is just a thin wrapper between MPI and Julia. To use this interface, you need an actual MPI library installed in your system such as OpenMPI or MPICH. Julia downloads and installs a MPI library for you, but it is also possible to use a MPI library already available in your system. This is useful, e.g., when running on HPC clusters. See the documentation of MPI.jl for further details.
To check that the package was installed properly, exit package mode by pressing the backspace key several times, and run it again
julia> incude("hello_mpi.jl")
Now, it should work, but you provably get output from a single MPI rank only.
Running MPI code¶
To run MPI applications in parallel, you need a launcher like mpiexec. MPI codes written in Julia are not an exception to this rule. From the system terminal, you can run
$ mpiexec -np 4 julia hello_mpi.jl
But it will provably don't work since the version of mpiexec needs to match with the MPI version we are using from Julia. You can find the path to the mpiexec binary you need to use with these commands
julia> using MPI
julia> MPI.mpiexec_path
and then try again
$ /path/to/my/mpiexec -np 4 julia hello_mpi.jl
with your particular path.
However, this is not very convenient. Don't worry if you could not make it work! A more elegant way to run MPI code is from the Julia REPL directly, by using these commands:
julia> using MPI
julia> mpiexec(cmd->run(`$cmd -np 4 julia hello_mpi.jl`))
Now, you should see output from 4 ranks.
Installing packages locally¶
We have installed the MPI package globally and it will be available in all Julia sessions. However, in some situations, we want to work with different versions of the same package or to install packages in an isolated way to avoid potential conflicts with other packages. This can be done by using local projects.
A project is simply a folder in the hard disk. To use a particular folder as your project, you need to activate it. This is done by entering package mode and using the activate command followed by the path to the folder you want to activate.
(@v1.8) pkg> activate .
Previous command will activate the current working directory. Note that the dot . is indeed the path to the current folder.
The prompt has changed to (lessons) pkg> indicating that we are in the project within the lessons folder. The particular folder name can be different in your case.
--project flag. The command $ julia --project=. will open Julia and activate a project in the current directory. You can also achieve the same effect by setting the environment variable JULIA_PROJECT with the path of the folder you want to activate.
(@v1.8) pkg> activate folderB and then julia> cd("folderA"), will activate the project in folderB and change the current working directory to folderA.
At this point all package-related operations will be local to the new project. For instance, install the DataFrames package.
(lessons) pkg> add DataFrames
Use the package to check that it is installed
julia> using DataFrames
julia> DataFrame(a=[1,2],b=[3,4])
Now, we can return to the global project to check that DataFrames has not been installed there. To return to the global environment, use activate without a folder name.
(lessons) pkg> activate
The prompt is again (@v1.8) pkg>
Now, try to use DataFrames.
julia> using DataFrames
julia> DataFrame(a=[1,2],b=[3,4])
You should get an error or a warning unless you already had DataFrames installed globally.
Project and Manifest files¶
The information about a project is stored in two files Project.toml and Manifest.toml.
Project.tomlcontains the packages explicitly installed (the direct dependencies)Manifest.tomlcontains direct and indirect dependencies along with the concrete version of each package.
In other words, Project.toml contains the packages relevant for the user, whereas Manifest.toml is the detailed snapshot of all dependencies. The Manifest.toml can be used to reproduce the same envinonment in another machine.
You can see the path to the current Project.toml file by using the status operator (or st in its short form) while in package mode
(@v1.8) pkg> status
The information about the Manifest.toml can be inspected by passing the -m flag.
(@v1.8) pkg> status -m
Installing packages from a project file¶
Project files can be used to install lists of packages defined by others. E.g., to install all the dependencies of a Julia application.
Assume that a colleague has sent to you a Project.toml file with this content:
[deps]
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195"
Copy the contents of previous code block into a file called Project.toml and place it in an empty folder named newproject. It is important that the file is named Project.toml. You can create a new folder from the REPL with
julia> mkdir("newproject")
To install all the packages registered in this file you need to activate the folder containing your Project.toml file
(@v1.8) pkg> activate newproject
and then instantiating it
(newproject) pkg> instantiate
The instantiate command will download and install all listed packages and their dependencies in just one click.
Getting help in package mode¶
You can get help about a particular package operator by writing help in front of it
(@v1.8) pkg> help activate
You can get an overview of all package commands by typing help alone
(@v1.8) pkg> help
Package operations in Julia code¶
In some situations it is required to use package commands in Julia code, e.g., to automatize installation and deployment of Julia applications. This can be done using the Pkg package. For instance
julia> using Pkg
julia> Pkg.status()
is equivalent to call status in package mode.
(@v1.8) pkg> status
Conclusion¶
We have learned the basics of how to work with Julia. Now, you should be ready to start learning more on the language. If you want to further dig into the topics we have covered here, you can take a look and the following links
- Julia Manual https://docs.julialang.org/en/v1/manual/getting-started/
- Package manager https://pkgdocs.julialang.org/v1/getting-started/
If you want to interact with the Julia community on discourse, sign in at https://discourse.julialang.org/