Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make: parallel build #1202

Merged
merged 14 commits into from
Dec 14, 2023
Merged

Conversation

liambeguin
Copy link
Contributor

PR Description

allow users to build using make -j to parallelize target builds.
As stated in the first commit message on my system, this allows to build libraries about 5 times faster.

This was tested on branch hdl_2021_r2, and rebased on master for the PR.
Unfortunately I can't test on v2023.1 at the moment, but since this doesn't touch the HDL or tcl scripts it should be alright.

PR Type

  • Bug fix (change that fixes an issue)
  • New feature (change that adds new functionality)
  • Breaking change (has dependencies in other repos or will cause CI to fail)

PR Checklist

  • I have followed the code style guidelines
  • I have performed a self-review of changes
  • I have compiled all hdl projects and libraries affected by this PR
  • I have tested in hardware affected projects, at least on relevant boards
  • I have commented my code, at least hard-to-understand parts
  • I have signed off all commits from this PR
  • I have updated the documentation (wiki pages, ReadMe files, Copyright etc)
  • I have not introduced new Warnings/Critical Warnings on compilation
  • I have added new hdl testbenches or updated existing ones

Drop shell for loops in favor of makefile pattern rules so that make can
directly run targets in parallel (using -j). This doesn't affect
Vivado's own settings.

Implicitly, this also fixes missing build dependencies such as:

	make: *** No rule to make target '../../../library/axi_clkgen/component.xml', needed by 'adrv9009_zcu102.sdk/system_top.xsa'.  Stop.

As a benchmark:

	$ lscpu
	Architecture:                    x86_64
	CPU op-mode(s):                  32-bit, 64-bit
	Byte Order:                      Little Endian
	Address sizes:                   46 bits physical, 48 bits virtual
	CPU(s):                          20
	On-line CPU(s) list:             0-19
	Thread(s) per core:              1
	Core(s) per socket:              14
	Socket(s):                       1
	NUMA node(s):                    1
	Vendor ID:                       GenuineIntel
	CPU family:                      6
	Model:                           154
	Model name:                      12th Gen Intel(R) Core(TM) i9-12900H
	Stepping:                        3
	CPU MHz:                         2900.000
	CPU max MHz:                     5000.0000
	CPU min MHz:                     400.0000
	BogoMIPS:                        5836.80
	...
	$ make -C projects/adrv9009/zcu102/ clean-all
	$ time make -C projects/adrv9009/zcu102/ lib
	...
	real    9m27.223s
	user    9m2.556s
	sys     0m32.358s

	$ make -C projects/adrv9009/zcu102/ clean-all
	$ time make -C projects/adrv9009/zcu102/ -j8 lib
	...
	real    1m54.639s
	user    16m26.512s
	sys     1m2.317s

i.e. about 5 times faster to build IP core dependencies.

Signed-off-by: Liam Beguin <[email protected]>
quiet.mk Outdated Show resolved Hide resolved
@@ -83,22 +83,24 @@ ifneq ($(XILINX_DEPS),)

XILINX_DEPS += $(GENERIC_DEPS)
XILINX_DEPS += $(HDL_LIBRARY_PATH)scripts/adi_ip_xilinx.tcl
XILINX_DEPS += $(foreach dep,$(XILINX_LIB_DEPS),$(HDL_LIBRARY_PATH)$(dep)/component.xml)
_XILINX_LIB_DEPS = $(foreach dep,$(XILINX_LIB_DEPS),$(HDL_LIBRARY_PATH)$(dep)/component.xml)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also do this to library/Makefile ?
I mean, move the project list to a variable to be used as a dependencies, so we can also use the -j .
There, I think it is better to keep the list instead of globing.

(if not, I can do it later also)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, I'll have a look

@gastmaier
Copy link
Contributor

gastmaier commented Oct 31, 2023

Hi @liambeguin, @AndreiGrozav commented that there is an issue with the pr that when a library fails during the generation of the component.xml file, the next make would consider that the build has been successful, because the file exists.
I also noticed that when I edit a library file, the edited library does not automatically rebuilds anymore, which is a regression.

Consider the following workflow

projects/pulsar_adc_pmdz$ make
Building pulsar_adc_pmdz_coraz7s project [/mnt/wsl/data/repos/hdl-dma/projects/pulsar_adc_pmdz/coraz7s/pulsar_adc_pmdz_coraz7s_vivado.log] ...

projects/pulsar_adc_pmdz$ vim ../../library/spi_engine/axi_spi_engine/axi_spi_engine_ip.tcl
projects/pulsar_adc_pmdz$ make
Building axi_spi_engine library [/mnt/wsl/data/repos/hdl-dma/library/spi_engine/axi_spi_engine/axi_spi_engine_ip.log] ... OK
Building pulsar_adc_pmdz_coraz7s project [/mnt/wsl/data/repos/hdl-dma/projects/pulsar_adc_pmdz/coraz7s/pulsar_adc_pmdz_coraz7s_vivado.log] ...

Notice how the library axi_spi_engine_ip should rebuild after being edited.

I think we have to:

  • properly set the libraries dependencies to be all files in the library path, or similar, so the Makefile compares their timestamp against the component.xml file.
  • remove the component.xml file when the lib build fails, like || (rm component.xml ; exit 1), handle the build error with the bash "or" and re-throw it.

@@ -91,7 +91,7 @@ xilinx: component.xml
component.xml: $(XILINX_DEPS) $(_XILINX_INTF_DEPS) $(_XILINX_LIB_DEPS)
-rm -rf $(CLEAN_TARGET)
$(call build, \
$(VIVADO) $(LIBRARY_NAME)_ip.tcl, \
flock component.xml -c "$(VIVADO) $(LIBRARY_NAME)_ip.tcl", \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks you for your initiative and effort. This optimization will be appreciated by everyone.

Let me continue with what I would change. There are two issues at this line:

  1. flock creates an empty component.xml, regardless of the success/fail status, an component.xml will result after the make call. So, when someone will call make, for the second time, a library that failed, will not be rebuild. Because the component.xml is there.

  2. We want any error in `the library build to stop the whole build. You wrote this in another commit:
    "Implicitly, this also fixes missing build dependencies such as:
    make: *** No rule to make target '../../../library/axi_clkgen/component.xml', needed by 'adrv9009_zcu102.sdk/system_top.xsa'. Stop."
    This is not a feature for us. If someone uses a release or stable branch, it does not matter that much. But in development it surely does. If a library build fails, the project build that depends on that library will fail in the end.
    With this in mind the uglier scenarios will arise on the support forums. For us, trying to figure out why a project build fails for someone who does not give us the whole log or does not states the modifications of libraries in a reference design.
    Also, working on a project with high resource demands, for which a build takes 3 hours or more will result in wasted time and resources for a developer or for our CI flow.
    My suggestions is to remove the component.xml if the build fails and pass the error status

     $(call build, \
             flock component.xml -c "$(VIVADO) $(LIBRARY_NAME)_ip.tcl", \
             $(LIBRARY_NAME)_ip.log, \
             $(HL)$(LIBRARY_NAME)$(NC) library) || (ERR=$$? && rm component.xml && exit $$ERR);
    

If you have a better solution, please add it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @AndreiGrozav,

Thanks for testing this, and apologies for the delay.

  1. flock creates an empty component.xml, regardless of the success/fail status, an component.xml will result after the make call. So, when someone will call make, for the second time, a library that failed, will not be rebuild. Because the component.xml is there.

interesting! I definitely missed that. I like your approach, I can't really find anything within flock to take care of cleaning up if the command fails.

actually, maybe .DELETE_ON_ERROR would work here. I don't know if we want to be more conservative and take care of this in individual targets.

Do you have a preference?

  1. We want any error in `the library build to stop the whole build.

I definitely agree with that, the commit message might be misleading. If I'm not mistaken, this error message happens if you try using make -j before applying any commits from this branch.
Assuming I address the issue in 1. if an IP core build fails the project target won't get run because make will detect an issue in build dependencies. The only difference with master is that it would finish current builds.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a preference.

fi; \
done

$(HDL_LIBRARY_PATH)%/component.xml:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change causes the project to be unable to track library changes.
Library dependencies are managed in library.mk, so we should always run make on all library dependencies and let library.mk manage and skip them.

I will commit this change to your branch, if you do not like it, feel free to revert it.

(The other issue with "a library that failed will not be rebuilt" I'll leave to @liambeguin and @AndreiGrozav, as I have no preference for either solution).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this related to what @AndreiGrozav was saying? about the fact that flock is creating a file even if the build fails?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's slightly different.
Andrei problem: a failed component.xml build have a newer timestamp than the dependencies (library.mk level).
My problem: if component.xml file exists, it never rebuilds the library even if the dependencies changes (xilinx-project.mk level).

library/Makefile Outdated
@@ -14,7 +14,7 @@ _LIBS := $(shell find . -mindepth 2 -name Makefile -exec dirname {} \; | sort)

FORCE:
$(_LIBS): FORCE
$(MAKE) -C $@ $(TARGET)
$(MAKE) -C $@
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect. $(TARGET) is a target-specific variables and is set on line 19. it also default to an empty string to build the default target.

Copy link
Contributor

@gastmaier gastmaier Nov 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct, sorry.
The issue was the lib: TARGET:="" which caused make (version 4.3) to throw the error:

make: *** empty string invalid as file name.  Stop.

When merging, we are going to squash these commits.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue was the lib: TARGET:="" which caused make (version 4.3) to throw the error

sorry about that.

should I still make the flock change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we need to remove the component.xml file if the build fails.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.DELETE_ON_ERROR: worked, thanks

liambeguin and others added 4 commits November 9, 2023 21:30
During a highly parallelized build, it's possible that multiple
identical targets be started simultaneously. This is exacerbated by long
target execution time.

Add an advisory lock on the component.xml file so that multiple
instances of Vivado don't try to overwrite the same file.

This doesn't prevent a target from being checked multiple times, but
forces it to only be run a single time.

DELETE_ON_ERROR is required here because flock will create component.xml
even if the target fails breaking dependencies at the project level.

Signed-off-by: Liam Beguin <[email protected]>
Search for all Makefiles under library/ and use the directory name to
generate a list of libraries to build.

With this scheme, `make lib` can be run in parallel.

Signed-off-by: Liam Beguin <[email protected]>
Shrink and parallelize clean targets by leveraging target-specific
variables. This allows us to reuse the generic component.xml target and
trigger a clean instead of a build.

Signed-off-by: Liam Beguin <[email protected]>
Library dependencies are managed in library.mk, this commit ensures
that library.mk manage and skip them by setting a dummy FORCE target.
When building a project, it is desired to rebuild all libraries that
have been modified.
Previously, the solution placed component.xml files as dependencies,
skipping these targets if the file already exists, but ignored changes
to them.

Signed-off-by: Jorge Marques <[email protected]>
SRaus
SRaus previously approved these changes Nov 10, 2023
quiet.mk Outdated Show resolved Hide resolved
Since we now support parallel build, differ message from starting and
finishing the build.
A more sophisticated solution could be develop but Makefile is not good
for shared global variables.

Signed-off-by: Jorge Marques <[email protected]>
gastmaier
gastmaier previously approved these changes Nov 10, 2023
Copy link
Contributor

@gastmaier gastmaier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The concerns have been addressed by the author and reviewers, and this PR effectively improves/speeds up our workflow and CI.
Great job @liambeguin!

@gastmaier
Copy link
Contributor

gastmaier commented Nov 10, 2023

There is a problem with intel libraries (e.g. intel/adi_jesd204 , intel/avl_adxcvr) that causes cd library ; make --dry-run to fail. (and of course the regular run). I have asked someone with more Intel experience to look into this (that person was me all along).

@liambeguin
Copy link
Contributor Author

Thanks @gastmaier !

There is a problem with intel libraries

The same changes can be made to the intel build, but since I don't have a setup to test on, I thought that could be done in a second pass.

Add support for touching .timestamp_intel as separated targets.

Signed-off-by: Jorge Marques <[email protected]>
Jorge.Marques and others added 3 commits November 10, 2023 18:35
xilinx and intel were set at lib target, having empty value at the actual
target (component.xml, .timestamp_intel), which default to building both.

Signed-off-by: Jorge Marques <[email protected]>
I mistakenly deleted the FORCE line in the last commit.

Signed-off-by: Jorge Marques <[email protected]>
Wrap library.mk files around a lock file, avoiding a vivado call when
other dependency already queue a vivado library call.
The next calls will properly resolve the dependencies against component.xml
timestamp and skip it.

Signed-off-by: Jorge Marques <[email protected]>
@gastmaier
Copy link
Contributor

gastmaier commented Nov 13, 2023

There is one issue with the flock approach.
Since we recursively call library.mk, make cannot orchestrate the library build properly, causing a vivado call on the same dependency multiple times when using a high -jX value.
To reproduce, add echo "BUILDING $(LIBRARY_NAME)" to library.mk component.xml target.
My last commit proposes replacing the file descriptor lock by a <library>/.lock file, before the recursive library.mk call,
to ensure the recursive call occurs after a previous Vivado call resolves, and also ensures that these subsequent call will properly do dependency against timestamp resolution, avoiding calling Vivado to build the same lib again.

Before the last commit:
BUILDING axi_clkgen
BUILDING axi_i2s_adi
BUILDING axi_spdif_tx
Building axi_i2s_adi library [/home/me/Documents/adi/hdl-make2/library/axi_i2s_adi/axi_i2s_adi_ip.log] ...
Building axi_clkgen library [/home/me/Documents/adi/hdl-make2/library/axi_clkgen/axi_clkgen_ip.log] ...
Building axi_spdif_tx library [/home/me/Documents/adi/hdl-make2/library/axi_spdif_tx/axi_spdif_tx_ip.log] ...
BUILDING axi_hdmi_tx
Building axi_hdmi_tx library [/home/me/Documents/adi/hdl-make2/library/axi_hdmi_tx/axi_hdmi_tx_ip.log] ...
BUILDING axi_ad4858
BUILDING util_cdc
Building axi_ad4858 library [/home/me/Documents/adi/hdl-make2/library/axi_ad4858/axi_ad4858_ip.log] ...
Building util_cdc library [/home/me/Documents/adi/hdl-make2/library/util_cdc/util_cdc_ip.log] ...
BUILDING axi_sysid
BUILDING sysid_rom
BUILDING util_i2c_mixer
Building axi_sysid library [/home/me/Documents/adi/hdl-make2/library/axi_sysid/axi_sysid_ip.log] ...
Building sysid_rom library [/home/me/Documents/adi/hdl-make2/library/sysid_rom/sysid_rom_ip.log] ...
Building util_i2c_mixer library [/home/me/Documents/adi/hdl-make2/library/util_i2c_mixer/util_i2c_mixer_ip.log] ...
BUILDING util_cpack2
BUILDING util_cdc
Building util_cpack2 library [/home/me/Documents/adi/hdl-make2/library/util_pack/util_cpack2/util_cpack2_ip.log] ...
Building util_cdc library [/home/me/Documents/adi/hdl-make2/library/util_cdc/util_cdc_ip.log] ...
BUILDING util_cdc
Building util_cdc library [/home/me/Documents/adi/hdl-make2/library/util_cdc/util_cdc_ip.log] ...
Build util_cdc library [/home/me/Documents/adi/hdl-make2/library/util_cdc/util_cdc_ip.log] FAILED
For details see /home/me/Documents/adi/hdl-make2/library/util_cdc/util_cdc_ip.log

make[2]: *** [../scripts/library.mk:95: component.xml] Error 1
make[2]: *** Deleting file 'component.xml'
make[1]: *** [../scripts/library.mk:104: ../util_cdc/component.xml] Error 2
make: *** [../../scripts/project-xilinx.mk:119: ../../../library/axi_pwm_gen/component.xml] Error 2
make: *** Waiting for unfinished jobs....
Build util_cdc library [/home/me/Documents/adi/hdl-make2/library/util_cdc/util_cdc_ip.log] OK
Build sysid_rom library [/home/me/Documents/adi/hdl-make2/library/sysid_rom/sysid_rom_ip.log] OK
Build axi_sysid library [/home/me/Documents/adi/hdl-make2/library/axi_sysid/axi_sysid_ip.log] OK
Build util_cdc library [/home/me/Documents/adi/hdl-make2/library/util_cdc/util_cdc_ip.log] OK
BUILDING util_axis_fifo
Building util_axis_fifo library [/home/me/Documents/adi/hdl-make2/library/util_axis_fifo/util_axis_fifo_ip.log] ...
Build axi_clkgen library [/home/me/Documents/adi/hdl-make2/library/axi_clkgen/axi_clkgen_ip.log] OK
Build util_i2c_mixer library [/home/me/Documents/adi/hdl-make2/library/util_i2c_mixer/util_i2c_mixer_ip.log] OK
Build axi_spdif_tx library [/home/me/Documents/adi/hdl-make2/library/axi_spdif_tx/axi_spdif_tx_ip.log] OK
Build util_cpack2 library [/home/me/Documents/adi/hdl-make2/library/util_pack/util_cpack2/util_cpack2_ip.log] OK
Build axi_i2s_adi library [/home/me/Documents/adi/hdl-make2/library/axi_i2s_adi/axi_i2s_adi_ip.log] OK
Build axi_hdmi_tx library [/home/me/Documents/adi/hdl-make2/library/axi_hdmi_tx/axi_hdmi_tx_ip.log] OK
Build util_axis_fifo library [/home/me/Documents/adi/hdl-make2/library/util_axis_fifo/util_axis_fifo_ip.log] OK
BUILDING axi_dmac
Building axi_dmac library [/home/me/Documents/adi/hdl-make2/library/axi_dmac/axi_dmac_ip.log] ...
Build axi_ad4858 library [/home/me/Documents/adi/hdl-make2/library/axi_ad4858/axi_ad4858_ip.log] OK
Build axi_dmac library [/home/me/Documents/adi/hdl-make2/library/axi_dmac/axi_dmac_ip.log] OK

After the last commit:
BUILDING axi_clkgen
Building axi_clkgen library [/home/me/Documents/adi/hdl-make/library/axi_clkgen/axi_clkgen_ip.log] ...
BUILDING axi_i2s_adi
Building axi_i2s_adi library [/home/me/Documents/adi/hdl-make/library/axi_i2s_adi/axi_i2s_adi_ip.log] ...
BUILDING util_i2c_mixer
BUILDING axi_hdmi_tx
BUILDING axi_sysid
Building util_i2c_mixer library [/home/me/Documents/adi/hdl-make/library/util_i2c_mixer/util_i2c_mixer_ip.log] ...
BUILDING sysid_rom
Building axi_hdmi_tx library [/home/me/Documents/adi/hdl-make/library/axi_hdmi_tx/axi_hdmi_tx_ip.log] ...
Building axi_sysid library [/home/me/Documents/adi/hdl-make/library/axi_sysid/axi_sysid_ip.log] ...
BUILDING axi_spdif_tx
Building sysid_rom library [/home/me/Documents/adi/hdl-make/library/sysid_rom/sysid_rom_ip.log] ...
BUILDING axi_ad4858
BUILDING util_cpack2
Building axi_spdif_tx library [/home/me/Documents/adi/hdl-make/library/axi_spdif_tx/axi_spdif_tx_ip.log] ...
Building axi_ad4858 library [/home/me/Documents/adi/hdl-make/library/axi_ad4858/axi_ad4858_ip.log] ...
Building util_cpack2 library [/home/me/Documents/adi/hdl-make/library/util_pack/util_cpack2/util_cpack2_ip.log] ...
BUILDING util_cdc
Building util_cdc library [/home/me/Documents/adi/hdl-make/library/util_cdc/util_cdc_ip.log] ...
Build util_cdc library [/home/me/Documents/adi/hdl-make/library/util_cdc/util_cdc_ip.log] OK
Build axi_sysid library [/home/me/Documents/adi/hdl-make/library/axi_sysid/axi_sysid_ip.log] OK
Build util_i2c_mixer library [/home/me/Documents/adi/hdl-make/library/util_i2c_mixer/util_i2c_mixer_ip.log] OK
BUILDING axi_pwm_gen
Building axi_pwm_gen library [/home/me/Documents/adi/hdl-make/library/axi_pwm_gen/axi_pwm_gen_ip.log] ...
BUILDING util_axis_fifo
Building util_axis_fifo library [/home/me/Documents/adi/hdl-make/library/util_axis_fifo/util_axis_fifo_ip.log] ...
Build sysid_rom library [/home/me/Documents/adi/hdl-make/library/sysid_rom/sysid_rom_ip.log] OK
Build axi_clkgen library [/home/me/Documents/adi/hdl-make/library/axi_clkgen/axi_clkgen_ip.log] OK
Build util_cpack2 library [/home/me/Documents/adi/hdl-make/library/util_pack/util_cpack2/util_cpack2_ip.log] OK
Build axi_spdif_tx library [/home/me/Documents/adi/hdl-make/library/axi_spdif_tx/axi_spdif_tx_ip.log] OK
Build axi_i2s_adi library [/home/me/Documents/adi/hdl-make/library/axi_i2s_adi/axi_i2s_adi_ip.log] OK
Build axi_hdmi_tx library [/home/me/Documents/adi/hdl-make/library/axi_hdmi_tx/axi_hdmi_tx_ip.log] OK
Build axi_pwm_gen library [/home/me/Documents/adi/hdl-make/library/axi_pwm_gen/axi_pwm_gen_ip.log] OK
Build util_axis_fifo library [/home/me/Documents/adi/hdl-make/library/util_axis_fifo/util_axis_fifo_ip.log] OK
BUILDING axi_dmac
Building axi_dmac library [/home/me/Documents/adi/hdl-make/library/axi_dmac/axi_dmac_ip.log] ...
Build axi_ad4858 library [/home/me/Documents/adi/hdl-make/library/axi_ad4858/axi_ad4858_ip.log] OK
Build axi_dmac library [/home/me/Documents/adi/hdl-make/library/axi_dmac/axi_dmac_ip.log] OK
Building ad4858_fmcz_zed project [/home/me/Documents/adi/hdl-make/projects/ad4858_fmcz/zed/ad4858_fmcz_zed_vivado.log] ...

Both with (cd projects/ad4858_fmcz/zed ; make -j16)Notice how Vivado is called once in util_cdc now.

@liambeguin
Copy link
Contributor Author

@gastmaier I did notice the same issue with highly parallelized builds

from 85e390e

This doesn't prevent a target from being checked multiple times, but forces it to only be run a single time.

but didn't think it was an issue since flock protects the file and the build is only run once.

Since the issue seems to be coming from the parent task not protecting properly, why not move the flock call there instead of implementing a custom lock?

maybe something like this:

 $(_XILINX_LIB_DEPS):
	flock $(dir $@)/component.xml -c "$(MAKE) -C $(dir $@) xilinx"

I think it also help to have _XILINX_LIB_DEPS keep track of component.xml files (instead of the directory). make is better at tracking actual files.

component.xml cannot be used as lock file because generating the lock
would create a new timestamp and library.mk would think the library is
up-to-date.

Signed-off-by: Jorge Marques <[email protected]>
@gastmaier
Copy link
Contributor

I pushed a solution with flock.
Even with flock we need to use a .lock file because when we "flock" the library.mk call, it creates a component.xml with a new timestamp, which library.mk compares against the dependencies and thinks the library is already built 😒 .
I will leave to Andrei to review it tomorrow and see what's better (3614ee3 or 4712b9d) (I personally prefer the flock one right now).

Catch error from the target command, instead of flock exit code.
Flock only exits with a error code for issues with the command itself,
like a timed out lock, never from target the command.

Signed-off-by: Jorge Marques <[email protected]>
@gastmaier
Copy link
Contributor

gastmaier commented Dec 6, 2023

For reviewers, a list of checks that should be answered 'yes' to pass.

# Built adv7511.zed project?
(make adv7511.zed -j8)

# Built pulsar_adc_pmdz.* projects?
(cd projects/pulsar_adc_pmdz ; make -j8)

# Cleaned all libs?
(cd library ; make clean)

# Built spi_engine/axi_spi_engine lib?
(cd library/spi_engine/axi_spi_engine; make)

# Cleaned all libs AND built all libs?
(cd library ; make clean all -j8)

# Supposing installed version != 2023.1 (force other error if not the case).
# In a error scenario, did the build exited/stopped after the error?
unset ADI_IGNORE_VERSION_CHECK
(cd projects/pulsar_adc_pmdz ; make -j8)

Also, does the commit create new artifacts? Are they properly git gitnored?

Fixup "make clean all" not executing second target since the
dependencies were the same.
Same approach as projects-toplevel.mk.

Signed-off-by: Jorge Marques <[email protected]>
Copy link
Contributor

@AndreiGrozav AndreiGrozav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some commit squashing should be done to clean thing up, before merging to main.

@gastmaier
Copy link
Contributor

I'll squash into a single, since individual commits are not functional in this case.
But we sure learned a few things in the process.

@gastmaier gastmaier merged commit 887ffac into analogdevicesinc:main Dec 14, 2023
1 of 2 checks passed
gastmaier added a commit that referenced this pull request Dec 29, 2023
The .lock file is used to forbid multiple concurrent builds of the same
library at the same time, allowing safe parallelization.
This should have been added to pr #1202.

Signed-off-by: Jorge Marques <[email protected]>
bia1708 pushed a commit to bia1708/hdl that referenced this pull request Apr 5, 2024
Drop shell for loops in favor of makefile pattern rules,
so make can run targets in parallel using -j.
This doesn't affect Vivado's own settings.

As a benchmark, 12th Gen Intel(R) Core(TM) i9-12900H 5GHz(max):
	$ make -C projects/adrv9009/zcu102/ clean-all
	$ time make -C projects/adrv9009/zcu102/ -j$CORES lib
CORES=1:
	real    9m27.223s
	user    9m2.556s
	sys     0m32.358s
CORES=8:
	real    1m54.639s
	user    16m26.512s
	sys     1m2.317s
i.e. about 5 times faster to build IP core dependencies.

Signed-off-by: Liam Beguin <[email protected]>
Signed-off-by: Jorge Marques <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants