Skip to content

Commit

Permalink
OCaml solutions: update to fix failing builds (#962)
Browse files Browse the repository at this point in the history
  • Loading branch information
gkpotter authored Feb 19, 2024
1 parent 7926368 commit bd2d164
Show file tree
Hide file tree
Showing 20 changed files with 192 additions and 98 deletions.
2 changes: 1 addition & 1 deletion PrimeOCaml/solution_1/.dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
_build
*.native
**/.DS_Store
2 changes: 1 addition & 1 deletion PrimeOCaml/solution_1/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
_build
*.native
**/.DS_Store
16 changes: 7 additions & 9 deletions PrimeOCaml/solution_1/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
FROM primeimages/ocaml:4.12-r1 AS build
FROM primeimages/ocaml:5.1 AS build

RUN mkdir /home/opam/primeocaml
WORKDIR /prime-ocaml

WORKDIR /home/opam/primeocaml
COPY . .

COPY *.ml ./
RUN dune build

RUN corebuild PrimeOCaml.native

FROM alpine:3.13
FROM alpine:3.19

WORKDIR /app
COPY --from=build /home/opam/primeocaml/PrimeOCaml.native PrimeOCaml.native
COPY --from=build /prime-ocaml/_build/install/default/bin/prime-ocaml prime-ocaml.exe

ENTRYPOINT [ "./PrimeOCaml.native" ]
ENTRYPOINT [ "./prime-ocaml.exe" ]
45 changes: 22 additions & 23 deletions PrimeOCaml/solution_1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,43 @@ A faithful implementation of the prime sieving algorithm in [OCaml](https://ocam

[OPAM](https://opam.ocaml.org) is the OCaml package manager. For more info on how to install both OCaml and OPAM, check out the OCaml [installation guide](https://ocaml.org/docs/install.html).

#### Install Core
[OCamlbuild](https://github.com/ocaml/ocamlbuild) is a convenient builder for simple projects, and [Core](https://opensource.janestreet.com/core/) is an alternative standard library for OCaml, which can be installed using OPAM via:
#### Install Libraries and Tools
This implementation uses [Core](https://opensource.janestreet.com/core/), which is an alternative standard library for OCaml, and [Dune](https://dune.build/) which is a build system for OCaml projects. These can be installed using OPAM via:
```
opam install ocamlbuild
opam install core
opam install core dune
```
#### Build and Run
Build and run using corebuild via:
#### Build and Run using Dune
Build and run using Dune via:
```
corebuild PrimeOcaml.native
./PrimeOCaml.native
dune build
dune exec prime-ocaml
```

### Docker
As an alternative to running locally, build and run using docker via:
As an alternative to running locally, build and run using [Docker](https://www.docker.com/) via:
```
docker build -t prime-ocaml .
docker run --rm prime-ocaml
```

## Output
**Machine:** MacBook Pro (16-inch, 2019)
**Machine:** MacBook Air (M2, 2022)

**Processor:** Intel Core i7 (I7-9750H) at 2.6 GHz
**Processor:** Apple M2

Example output running *locally* with OCaml 4.10:
Example output running *locally* with OCaml 5.1:
```
gkpotter-faithful;953;5.002805;1
gkpotter-faithful;943;5.000744;1
gkpotter-faithful;938;5.000446;1
gkpotter-faithful;939;5.002426;1
gkpotter-faithful;955;5.002166;1
gkpotter-faithful;1263;5.003109;1;algorithm=base,faithful=yes
gkpotter-faithful;1266;5.001691;1;algorithm=base,faithful=yes
gkpotter-faithful;1288;5.003413;1;algorithm=base,faithful=yes
gkpotter-faithful;1276;5.002650;1;algorithm=base,faithful=yes
gkpotter-faithful;1285;5.000810;1;algorithm=base,faithful=yes
```
Example output running *via Docker* with OCaml 4.12:
Example output running *via Docker* with OCaml 5.1:
```
gkpotter-faithful;724;5.002301;1
gkpotter-faithful;718;5.001542;1
gkpotter-faithful;731;5.009693;1
gkpotter-faithful;728;5.000515;1
gkpotter-faithful;731;5.005918;1
gkpotter-faithful;1207;5.000417;1;algorithm=base,faithful=yes
gkpotter-faithful;1221;5.001276;1;algorithm=base,faithful=yes
gkpotter-faithful;1241;5.000009;1;algorithm=base,faithful=yes
gkpotter-faithful;1240;5.002623;1;algorithm=base,faithful=yes
gkpotter-faithful;1214;5.002387;1;algorithm=base,faithful=yes
```
4 changes: 4 additions & 0 deletions PrimeOCaml/solution_1/bin/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(executable
(public_name prime-ocaml)
(name main)
(libraries core PrimeOCaml))
17 changes: 17 additions & 0 deletions PrimeOCaml/solution_1/bin/main.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
open Core
open PrimeOCaml

let () =
let now_in_seconds_as_float () = (Int63.to_float (Time_ns.to_int63_ns_since_epoch (Time_ns.now ()))) /. 1000000000.0 in
let start_time = now_in_seconds_as_float () in
let limit = 1000000 in
let sieve = Ref.create (new prime_sieve limit) in
let passes = Ref.create 0 in
while Float.(<) ((now_in_seconds_as_float ()) -. start_time) 5.0 do
sieve := new prime_sieve limit;
!sieve#run_sieve;
passes := !passes + 1
done;
let duration = (now_in_seconds_as_float ()) -. start_time in
!sieve#print_results false duration !passes;
;;
13 changes: 13 additions & 0 deletions PrimeOCaml/solution_1/dune-project
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
(lang dune 3.13)

(name prime-ocaml)

(generate_opam_files true)

(authors "Greyson Potter <https://github.com/gkpotter>")

(package
(name prime-ocaml)
(synopsis "A faithful implementation of Dave Plummer's prime
sieving algorithm in OCaml.")
(depends ocaml core dune))
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(*
Greyson Potter - 04/18/2021 - https://github.com/gkpotter
PrimeOCamlFunctional.ml : A functional implementation of Dave Plummer's prime
PrimeOCaml.ml : A faithful implementation of Dave Plummer's prime
sieving algorithm in OCaml.
*)

Expand Down Expand Up @@ -74,16 +74,3 @@ class prime_sieve limit =
end
;;

let () =
let start_time = Unix.gettimeofday () in
let limit = 1000000 in
let sieve = Ref.create (new prime_sieve limit) in
let passes = Ref.create 0 in
while Float.(<) ((Unix.gettimeofday ()) -. start_time) 5.0 do
sieve := new prime_sieve limit;
!sieve#run_sieve;
passes := !passes + 1
done;
let duration = ((Unix.gettimeofday ()) -. start_time) in
!sieve#print_results false duration !passes;
;;
3 changes: 3 additions & 0 deletions PrimeOCaml/solution_1/lib/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(library
(name PrimeOCaml)
(libraries core))
26 changes: 26 additions & 0 deletions PrimeOCaml/solution_1/prime-ocaml.opam
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
synopsis: """
A faithful implementation of Dave Plummer's prime
sieving algorithm in OCaml."""
authors: ["Greyson Potter <https://github.com/gkpotter>"]
depends: [
"ocaml"
"core"
"dune" {>= "3.13"}
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
[
"dune"
"build"
"-p"
name
"-j"
jobs
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
]
2 changes: 1 addition & 1 deletion PrimeOCaml/solution_2/.dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
_build
*.native
**/.DS_Store
2 changes: 1 addition & 1 deletion PrimeOCaml/solution_2/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
_build
*.native
**/.DS_Store
16 changes: 7 additions & 9 deletions PrimeOCaml/solution_2/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
FROM primeimages/ocaml:4.12-r1 AS build
FROM primeimages/ocaml:5.1 AS build

RUN mkdir /home/opam/primeocaml
WORKDIR /prime-ocaml-functional

WORKDIR /home/opam/primeocaml
COPY . .

COPY *.ml ./
RUN dune build

RUN corebuild PrimeOCamlFunctional.native

FROM alpine:3.13
FROM alpine:3.19

WORKDIR /app
COPY --from=build /home/opam/primeocaml/PrimeOCamlFunctional.native PrimeOCamlFunctional.native
COPY --from=build /prime-ocaml-functional/_build/install/default/bin/prime-ocaml-functional prime-ocaml-functional.exe

ENTRYPOINT [ "./PrimeOCamlFunctional.native" ]
ENTRYPOINT [ "./prime-ocaml-functional.exe" ]
48 changes: 24 additions & 24 deletions PrimeOCaml/solution_2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,52 @@
![Parallelism](https://img.shields.io/badge/Parallel-no-green)
![Bit count](https://img.shields.io/badge/Bits-unknown-yellowgreen)

An unfaithful implementation of the prime sieving algorithm using a functional approach in [OCaml](https://ocaml.org).
A functional implementation of the prime sieving algorithm in [OCaml](https://ocaml.org).

## Run Instructions

### Run Locally
#### Install OCaml and OPAM:

[OPAM](https://opam.ocaml.org) is the OCaml package manager. For more info on how to install both OCaml and OPAM, check out the OCaml [installation guide](https://ocaml.org/docs/install.html).

#### Install OCamlbuild and Core
[OCamlbuild](https://github.com/ocaml/ocamlbuild) is a convenient builder for simple projects, and [Core](https://opensource.janestreet.com/core/) is an alternative standard library for OCaml, both of which can be installed using OPAM via:
#### Install Libraries and Tools
This implementation uses [Core](https://opensource.janestreet.com/core/), which is an alternative standard library for OCaml, and [Dune](https://dune.build/) which is a build system for OCaml projects. These can be installed using OPAM via:
```
opam install ocamlbuild
opam install core
opam install core dune
```
#### Build and Run
Build and run using corebuild via:
#### Build and Run using Dune
Build and run using Dune via:
```
corebuild PrimeOcamlFunctional.native
./PrimeOCamlFunctional.native
dune build
dune exec prime-ocaml-functional
```

### Docker
As an alternative to running locally, build and run using docker via:
As an alternative to running locally, build and run using [Docker](https://www.docker.com/) via:
```
docker build -t prime-ocaml-functional .
docker run --rm prime-ocaml-functional
```

## Output
**Machine:** MacBook Pro (16-inch, 2019)
**Machine:** MacBook Air (M2, 2022)

**Processor:** Intel Core i7 (I7-9750H) at 2.6 GHz
**Processor:** Apple M2

Example output running *locally* with OCaml 4.10:
Example output running *locally* with OCaml 5.1:
```
gkpotter-unfaithful;954;5.004650;1
gkpotter-unfaithful;948;5.003024;1
gkpotter-unfaithful;941;5.000812;1
gkpotter-unfaithful;913;5.003839;1
gkpotter-unfaithful;935;5.000789;1
gkpotter-unfaithful;1350;5.001539;1;algorithm=base,faithful=no
gkpotter-unfaithful;1359;5.001631;1;algorithm=base,faithful=no
gkpotter-unfaithful;1372;5.001619;1;algorithm=base,faithful=no
gkpotter-unfaithful;1366;5.001790;1;algorithm=base,faithful=no
gkpotter-unfaithful;1329;5.001237;1;algorithm=base,faithful=no
```
Example output running *via Docker* with OCaml 4.12:
Example output running *via Docker* with OCaml 5.1:
```
gkpotter-unfaithful;702;5.006194;1
gkpotter-unfaithful;708;5.001435;1
gkpotter-unfaithful;708;5.003118;1
gkpotter-unfaithful;707;5.006474;1
gkpotter-unfaithful;704;5.003153;1
gkpotter-unfaithful;1272;5.002131;1;algorithm=base,faithful=no
gkpotter-unfaithful;1256;5.000893;1;algorithm=base,faithful=no
gkpotter-unfaithful;1273;5.000340;1;algorithm=base,faithful=no
gkpotter-unfaithful;1263;5.003227;1;algorithm=base,faithful=no
gkpotter-unfaithful;1269;5.001596;1;algorithm=base,faithful=no
```
4 changes: 4 additions & 0 deletions PrimeOCaml/solution_2/bin/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(executable
(public_name prime-ocaml-functional)
(name main)
(libraries core PrimeOCamlFunctional))
18 changes: 18 additions & 0 deletions PrimeOCaml/solution_2/bin/main.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
open Core
open PrimeOCamlFunctional

let () =
let now_in_seconds_as_float () = (Int63.to_float (Time_ns.to_int63_ns_since_epoch (Time_ns.now ()))) /. 1000000000.0 in
let start_time = now_in_seconds_as_float () in
let limit = 1000000 in
let rec run_test sieve passes =
if Float.(>) ((now_in_seconds_as_float ()) -. start_time) 5.0 then
let duration = ((now_in_seconds_as_float ()) -. start_time) in
print_results sieve false duration passes
else
let sieve = (create_sieve limit) in
run_sieve sieve;
run_test sieve (passes+1)
in
run_test (create_sieve limit) 0
;;
13 changes: 13 additions & 0 deletions PrimeOCaml/solution_2/dune-project
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
(lang dune 3.13)

(name prime-ocaml-functional)

(generate_opam_files true)

(authors "Greyson Potter <https://github.com/gkpotter>")

(package
(name prime-ocaml-functional)
(synopsis "A functional implementation of Dave Plummer's prime
sieving algorithm in OCaml.")
(depends ocaml core dune))
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,4 @@ let print_results sieve show_results duration passes =

let create_sieve limit =
{sieve_size = limit; raw_bits = (Array.init ((limit+1)/2) ~f:(fun _ -> true))}
;;

let () =
let start_time = Unix.gettimeofday () in
let limit = 1000000 in
let rec run_test sieve passes =
if Float.(>) ((Unix.gettimeofday ()) -. start_time) 5.0 then
let duration = ((Unix.gettimeofday ()) -. start_time) in
print_results sieve false duration passes
else
let sieve = (create_sieve limit) in
run_sieve sieve;
run_test sieve (passes+1)
in
run_test (create_sieve limit) 0
;;
3 changes: 3 additions & 0 deletions PrimeOCaml/solution_2/lib/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(library
(name PrimeOCamlFunctional)
(libraries core))
Loading

0 comments on commit bd2d164

Please sign in to comment.