Hi all,
I am working on writing a library for large chunked & compressed multidimensional arrays. I was working on a adding a feature to support sharding of array “chunks”. The way this works is that sharding further splits array chunks into sub-chunks that can be stored in a single “shard”. These sub-chunks have a set of codecs that are applied to them to compress them before storing them in a shard. The way the sharding process is defined requires one to implement the functionality in a recursive manner: see here. This image kind of illustrates what is required .
$ dune build
Error: dependency cycle between modules in _build/default/lib:
Storage
-> Array_to_bytes
-> Array_to_bytes
-> required by _build/default/lib/zarr.a
-> required by alias lib/all
-> required by alias default
I spoke to @shonfeder and they recommended I open a github issue on the dune project since it is not clear why I keep getting this compile error; but I wanted to read what others think before I do.
Indeed! First, I cannot figure out why Array_to_bytes is determined to have a cyclical dependency on itself: nothing in the modules itself should entail this afaict. Second, as a usability issue, I would expect that any detected dependency cycle should come with clear, legible instructions that indicate how to resolve it. That is not the case here, so this looks to me like a UI but at least.
That said, I expect more some with deeper dune and compiler expertise should be able to help diagnose here.
@zoj613 if you get a chance, trying to reduce your example to a minimal reproduction, by systematically cutting out parts of the project (e.g., removing nested dirs, removing modules that aren’t involved in the cycle) should help narrow down the problem.
If we look at _build/default/lib/.zarr.objs/zarr__Array_to_bytes.impl.all-deps, we can see that zarr__Array_to_bytes is in there; that’s not quite right.
After digging a bit, the cycle seems to be (or rather one cycle is):
in array_to_bytes.ml, Array_to_bytes depends on Metadata
in metadata.mli, Metadata depends on Codecs
in codecs.mli, Codecs depends on Array_to_bytes
This kind of cycle is not supported.
I think that’s equivalent to a library with modules A and B arranged like this:
(* a.mli *)
type t = int
val x:t
(* a.ml *)
type t = int
let (x:B.t) = 0
(* b.mli *)
type t = A.t
(* b.ml *)
type t = A.t
Note that even in codept this specific case would require a new warning for transitive dependencies in interfaces that don’t exist at the implementation level.
Thank you for this reply. This actually helped me realize that the cycle is caused by using a sub-module of Metadata in both Metadata and in Array_to_bytes. Moving the re-usable pieces of code inside the Metadata module into their own standalone module got rid of the dependancy cycle. See this commit: ... · zoj613/zarr-ml@8980748 · GitHub