forked from rarias/jungle
298 lines
7.0 KiB
Nix
298 lines
7.0 KiB
Nix
{
|
|
lib,
|
|
stdenv,
|
|
callPackage,
|
|
dpkg,
|
|
fetchurl,
|
|
|
|
sqlite,
|
|
elfutils,
|
|
}:
|
|
|
|
let
|
|
inherit (builtins)
|
|
attrNames
|
|
attrValues
|
|
concatMap
|
|
elem
|
|
filter
|
|
fromJSON
|
|
getAttr
|
|
groupBy
|
|
head
|
|
isNull
|
|
listToAttrs
|
|
map
|
|
mapAttrs
|
|
readFile
|
|
replaceStrings
|
|
splitVersion
|
|
;
|
|
inherit (lib)
|
|
converge
|
|
findFirst
|
|
groupBy'
|
|
hasPrefix
|
|
optional
|
|
pipe
|
|
take
|
|
toInt
|
|
toList
|
|
versionAtLeast
|
|
versionOlder
|
|
;
|
|
|
|
aptData = fromJSON (readFile ./packages.json);
|
|
|
|
# Compare versions in debian control file syntax
|
|
# See: https://www.debian.org/doc/debian-policy/ch-relationships.html#syntax-of-relationship-fields
|
|
#
|
|
# NOTE: this is not a proper version comparison
|
|
#
|
|
# A proper version solver, should aggregate dependencies with the same name
|
|
# and compute the constraint (e.g. a (>= 2) a (<< 5) -> 2 <= a << 5)
|
|
#
|
|
# But in the intel repo, there are no such "duplicated" dependencies to specify
|
|
# upper limits, which leads to issues when intel-hpckit-2021 depends on things
|
|
# like intel-basekit >= 2021.1.0-2403 and we end up installing the newest
|
|
# basekit instead of the one from 2021.
|
|
#
|
|
# To mitigate this, >= is set to take the latest version with matching major
|
|
# and minor (only revision and patch are allowed to change)
|
|
compareVersions =
|
|
got: kind: want:
|
|
let
|
|
g0 = take 2 (splitVersion got);
|
|
w0 = take 2 (splitVersion want);
|
|
in
|
|
if isNull want then
|
|
true
|
|
else if kind == "=" then
|
|
got == want
|
|
else if kind == "<<" then
|
|
versionOlder got want
|
|
else if kind == "<=" then
|
|
versionAtLeast want got
|
|
else if kind == ">>" then
|
|
versionOlder want got
|
|
else if kind == ">=" then
|
|
(g0 == w0) && versionAtLeast got want # always match major version
|
|
else
|
|
throw "unknown operation: ${kind}";
|
|
|
|
findMatching =
|
|
{
|
|
pname,
|
|
kind,
|
|
version,
|
|
}:
|
|
findFirst (x: pname == x.pname && compareVersions x.version kind version) null aptData;
|
|
|
|
isIntel = pkg: (hasPrefix "intel-" pkg.pname);
|
|
|
|
expandDeps =
|
|
pkg: (map findMatching (filter isIntel pkg.dependencies)) ++ (optional (pkg.size != 0) pkg);
|
|
|
|
# get the oldest by major version. If they have the same major version, take
|
|
# the newest. This prevents most issues with resolutions
|
|
# versionOlder b a -> true if b is older than a (b `older` a)
|
|
getNewerInMajor =
|
|
a: b:
|
|
let
|
|
va = a.version;
|
|
vb = b.version;
|
|
va0 = head (splitVersion va);
|
|
vb0 = head (splitVersion vb);
|
|
in
|
|
if isNull a then
|
|
b
|
|
else if va0 != vb0 then
|
|
if va0 > vb0 then b else a
|
|
else if versionOlder vb va then
|
|
a
|
|
else
|
|
b;
|
|
removeDups = l: attrValues (groupBy' getNewerInMajor null (getAttr "provides") l);
|
|
|
|
_resolveDeps = converge (l: removeDups (concatMap expandDeps l));
|
|
resolveDeps =
|
|
pkg:
|
|
let
|
|
deps = _resolveDeps (toList pkg);
|
|
namedDeps = (map (x: "${x.pname}-${x.version}") deps);
|
|
in
|
|
builtins.traceVerbose (builtins.deepSeq namedDeps namedDeps) deps;
|
|
|
|
blacklist = [
|
|
"intel-basekit-env"
|
|
"intel-basekit-getting-started"
|
|
"intel-hpckit-env"
|
|
"intel-hpckit-getting-started"
|
|
"intel-oneapi-advisor"
|
|
"intel-oneapi-common-licensing"
|
|
"intel-oneapi-common-oneapi-vars"
|
|
"intel-oneapi-common-vars"
|
|
"intel-oneapi-compiler-cpp-eclipse-cfg"
|
|
"intel-oneapi-compiler-dpcpp-eclipse-cfg"
|
|
"intel-oneapi-condaindex"
|
|
"intel-oneapi-dev-utilities-eclipse-cfg"
|
|
"intel-oneapi-dpcpp-ct-eclipse-cfg"
|
|
"intel-oneapi-eclipse-ide"
|
|
"intel-oneapi-hpc-toolkit-getting-started"
|
|
"intel-oneapi-icc-eclipse-plugin-cpp"
|
|
"intel-oneapi-vtune"
|
|
"intel-oneapi-vtune-eclipse-plugin-vtune"
|
|
];
|
|
|
|
isInBlacklist = pkg: elem pkg.provides blacklist;
|
|
removeBlacklist = filter (e: !(isInBlacklist e));
|
|
|
|
dpkgExtractAll =
|
|
pname: version:
|
|
{ srcs, deps }:
|
|
stdenv.mkDerivation {
|
|
inherit pname version srcs;
|
|
|
|
nativeBuildInputs = [ dpkg ];
|
|
phases = [ "installPhase" ];
|
|
|
|
passthru = { inherit deps; };
|
|
|
|
installPhase = ''
|
|
mkdir -p $out
|
|
for src in $srcs; do
|
|
echo "Unpacking $src"
|
|
dpkg -x $src $out
|
|
done
|
|
'';
|
|
};
|
|
|
|
apthost = "https://apt.repos.intel.com/oneapi/";
|
|
fetchDeb =
|
|
p:
|
|
fetchurl {
|
|
url = apthost + p.filename;
|
|
inherit (p) sha256;
|
|
};
|
|
|
|
buildIntel =
|
|
pkg:
|
|
pipe pkg [
|
|
resolveDeps
|
|
removeBlacklist
|
|
(l: {
|
|
srcs = map fetchDeb l;
|
|
deps = l;
|
|
})
|
|
(dpkgExtractAll "${pkg.provides}-extracted" pkg.version)
|
|
];
|
|
|
|
findHpcKit =
|
|
year:
|
|
findMatching {
|
|
pname = "intel-hpckit";
|
|
kind = "<<";
|
|
version = toString (year + 1);
|
|
};
|
|
years = map toInt (attrNames components);
|
|
|
|
patchIntel = callPackage ./patch_intel.nix { };
|
|
|
|
# Version information for each hpckit. This is used to normalize the paths
|
|
# so that files are in $out/{bin,lib,include...} instead of all over the place
|
|
# in $out/opt/intel/oneapi/*/*/{...}.
|
|
#
|
|
# The most important is the compiler component, which is used to build the
|
|
# stdenv for the hpckit.
|
|
#
|
|
# NOTE: this have to be manually specified, so we can avoid IFD. To add a
|
|
# new version, add a new field with an empty attrset, (e.g. "2026" = {}; ),
|
|
# build hpckit_2026.unpatched and use the values from
|
|
# result/opt/intel/oneapi/* to populate the attrset.
|
|
#
|
|
# WARN: if there are more than one version in the folders of the unpatched
|
|
# components, our dependency resolution hacks have probably failed and the
|
|
# package set may be broken.
|
|
components = {
|
|
"2025" = {
|
|
ishmem = "1.4";
|
|
pti = "0.13";
|
|
tcm = "1.4";
|
|
umf = "0.11";
|
|
|
|
ccl = "2021.16";
|
|
compiler = "2025.2";
|
|
dal = "2025.8";
|
|
debugger = "2025.2";
|
|
dev-utilities = "2025.2";
|
|
dnnl = "2025.2";
|
|
dpcpp-ct = "2025.2";
|
|
dpl = "2022.9";
|
|
ipp = "2022.2";
|
|
ippcp = "2025.2";
|
|
mkl = "2025.2";
|
|
mpi = "2021.16";
|
|
tbb = "2022.2";
|
|
};
|
|
"2024" = {
|
|
tcm = "1.1";
|
|
|
|
ccl = "2021.13";
|
|
compiler = "2024.2";
|
|
dal = "2024.6";
|
|
debugger = "2024.2";
|
|
dev-utilities = "2024.2";
|
|
diagnostics = "2024.2";
|
|
dnnl = "2024.2";
|
|
dpcpp-ct = "2024.2";
|
|
dpl = "2022.6";
|
|
ipp = "2021.12";
|
|
ippcp = "2021.12";
|
|
mkl = "2024.2";
|
|
mpi = "2021.13";
|
|
tbb = "2021.13";
|
|
|
|
extraPackages = [
|
|
sqlite
|
|
elfutils
|
|
];
|
|
};
|
|
};
|
|
|
|
replaceDots = replaceStrings [ "." ] [ "_" ];
|
|
|
|
in
|
|
lib.recurseIntoAttrs (
|
|
listToAttrs (
|
|
map (
|
|
year:
|
|
let
|
|
year_str = toString year;
|
|
in
|
|
{
|
|
name = "hpckit_${year_str}";
|
|
value = patchIntel {
|
|
unpatched = buildIntel (findHpcKit year);
|
|
components = components.${year_str};
|
|
};
|
|
}
|
|
) years
|
|
)
|
|
)
|
|
// {
|
|
apt = pipe aptData [
|
|
(groupBy (p: replaceDots p.provides))
|
|
(mapAttrs (
|
|
_: l:
|
|
listToAttrs (
|
|
map (pkg: {
|
|
name = replaceDots ("v" + pkg.version);
|
|
value = pkg;
|
|
}) l
|
|
)
|
|
))
|
|
];
|
|
|
|
inherit resolveDeps patchIntel buildIntel;
|
|
}
|