Skip to content

Commit 2411b0b

Browse files
committed
add OpenCL support
1 parent 323402a commit 2411b0b

File tree

1 file changed

+211
-9
lines changed

1 file changed

+211
-9
lines changed

environment/src/lib.rs

Lines changed: 211 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub fn install_env(env: &str) {
7777
.status()
7878
} else {
7979
println!(
80-
"\x1b[32m[xtask]\x1b[0m No supported package manager found (apt-get, dnf, yum, pacman). Please install Python manually."
80+
"\x1b[31m[xtask]\x1b[0m No supported package manager found (apt-get, dnf, yum, pacman). Please install Python manually."
8181
);
8282
return;
8383
}
@@ -89,12 +89,12 @@ pub fn install_env(env: &str) {
8989
}
9090
Ok(status) => {
9191
println!(
92-
"\x1b[32m[xtask]\x1b[0m Python installation failed, exit code: {:?}",
92+
"\x1b[31m[xtask]\x1b[0m Python installation failed, exit code: {:?}",
9393
status.code()
9494
)
9595
}
9696
Err(e) => println!(
97-
"\x1b[32m[xtask]\x1b[0m Error occurred while running install command: {e}"
97+
"\x1b[31m[xtask]\x1b[0m Error occurred while running install command: {e}"
9898
),
9999
}
100100
}
@@ -138,11 +138,11 @@ pub fn install_env(env: &str) {
138138
println!("\x1b[32m[xtask]\x1b[0m xmake installation completed!")
139139
}
140140
Ok(status) => println!(
141-
"\x1b[32m[xtask]\x1b[0m xmake installation failed, exit code: {:?}",
141+
"\x1b[31m[xtask]\x1b[0m xmake installation failed, exit code: {:?}",
142142
status.code()
143143
),
144144
Err(e) => println!(
145-
"\x1b[32m[xtask]\x1b[0m Error occurred while running install command: {e}"
145+
"\x1b[31m[xtask]\x1b[0m Error occurred while running install command: {e}"
146146
),
147147
}
148148
}
@@ -191,7 +191,7 @@ pub fn install_env(env: &str) {
191191
"\x1b[32m[xtask]\x1b[0m The highest CUDA version supported by your driver is {version_str}"
192192
);
193193
println!(
194-
"\x1b[32m[xtask]\x1b[0m You can also visit https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html to find the CUDA version compatible with your GPU driver."
194+
"\x1b[33m[xtask]\x1b[0m You can also visit https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html to find the CUDA version compatible with your GPU driver."
195195
);
196196
}
197197
}
@@ -200,17 +200,219 @@ pub fn install_env(env: &str) {
200200
);
201201
} else {
202202
println!(
203-
"\x1b[32m[xtask]\x1b[0m nvidia-smi not found. Please make sure you have an NVIDIA GPU and drivers installed."
203+
"\x1b[31m[xtask]\x1b[0m nvidia-smi not found. Please make sure you have an NVIDIA GPU and drivers installed."
204204
);
205205
}
206206

207207
println!();
208208
println!(
209-
"\x1b[32m[xtask]\x1b[0m Please visit https://developer.nvidia.com/cuda-toolkit-archive to select and download the appropriate CUDA version for your driver."
209+
"\x1b[33m[xtask]\x1b[0m Please visit https://developer.nvidia.com/cuda-toolkit-archive to select and download the appropriate CUDA version for your driver."
210210
);
211211
}
212+
"OpenCL" => {
213+
println!(
214+
"\x1b[32m[xtask]\x1b[0m The current automatic installation script only supports OpenCL installation for Intel CPU on Windows or Ubuntu systems."
215+
);
216+
println!("\x1b[32m[xtask]\x1b[0m Checking if OpenCL is already installed...");
217+
println!();
218+
219+
// Check if OpenCL is installed
220+
#[cfg(target_os = "windows")]
221+
{
222+
let clinfo_path = std::path::Path::new("clinfo.exe");
223+
if !clinfo_path.exists() {
224+
println!("\x1b[32m[xtask]\x1b[0m Downloading clinfo tool...");
225+
let download_status = std::process::Command::new("curl")
226+
.args(["-o", "clinfo.exe", "https://github.com/ahoylabs/clinfo/releases/download/master-d2baa06/clinfo.exe"])
227+
.status();
228+
229+
if let Err(e) = download_status {
230+
println!("\x1b[31m[xtask]\x1b[0m Failed to download clinfo: {}", e);
231+
println!("\x1b[33m[xtask]\x1b[0m You may need to enable proxy.");
232+
println!(
233+
"\x1b[33m[xtask]\x1b[0m You can also manually download from https://github.com/ahoylabs/clinfo/releases/download/master-d2baa06/clinfo.exe"
234+
);
235+
return;
236+
}
237+
}
238+
239+
let output = std::process::Command::new("clinfo.exe")
240+
.output()
241+
.expect("Failed to execute clinfo.exe");
242+
243+
let clinfo_output = String::from_utf8_lossy(&output.stdout);
244+
if let Some(line) = clinfo_output
245+
.lines()
246+
.find(|line| line.contains("Number of platforms"))
247+
{
248+
if let Some(number) = line.split_whitespace().last() {
249+
if number == "0" {
250+
println!("\x1b[32m[xtask]\x1b[0m OpenCL is not installed.");
251+
} else {
252+
println!(
253+
"\x1b[32m[xtask]\x1b[0m OpenCL is installed. Number of platforms: {}",
254+
number
255+
);
256+
return;
257+
}
258+
} else {
259+
println!("\x1b[31m[xtask]\x1b[0m Failed to parse the number of platforms.");
260+
}
261+
} else {
262+
println!(
263+
"\x1b[31m[xtask]\x1b[0m Failed to find 'Number of platforms' in clinfo output."
264+
);
265+
}
266+
}
267+
#[cfg(not(target_os = "windows"))]
268+
{
269+
let has_cmd = |cmd: &str| {
270+
std::process::Command::new("sh")
271+
.arg("-c")
272+
.arg(format!("command -v {}", cmd))
273+
.stdout(std::process::Stdio::null())
274+
.status()
275+
.map(|s| s.success())
276+
.unwrap_or(false)
277+
};
278+
279+
if !has_cmd("clinfo") {
280+
if has_cmd("apt") {
281+
println!("\x1b[32m[xtask]\x1b[0m Installing clinfo tool...");
282+
let install_status = std::process::Command::new("sh")
283+
.arg("-c")
284+
.arg("sudo apt update && sudo apt install opencl-headers ocl-icd-opencl-dev -y")
285+
.status();
286+
287+
if let Err(e) = install_status {
288+
println!("\x1b[31m[xtask]\x1b[0m Failed to install clinfo: {}", e);
289+
return;
290+
}
291+
} else {
292+
println!(
293+
"\x1b[31m[xtask]\x1b[0m Unsupported package manager. Please install clinfo manually."
294+
);
295+
return;
296+
}
297+
}
298+
299+
let output = std::process::Command::new("clinfo")
300+
.output()
301+
.expect("Failed to execute clinfo");
302+
303+
let clinfo_output = String::from_utf8_lossy(&output.stdout);
304+
if let Some(line) = clinfo_output
305+
.lines()
306+
.find(|line| line.contains("Number of platforms"))
307+
{
308+
if let Some(number) = line.split_whitespace().last() {
309+
if number == "0" {
310+
println!("\x1b[32m[xtask]\x1b[0m OpenCL is not installed.");
311+
} else {
312+
println!(
313+
"\x1b[32m[xtask]\x1b[0m OpenCL is installed. Number of platforms: {}",
314+
number
315+
);
316+
return;
317+
}
318+
} else {
319+
println!("\x1b[31m[xtask]\x1b[0m Failed to parse the number of platforms.");
320+
}
321+
} else {
322+
println!(
323+
"\x1b[31m[xtask]\x1b[0m Failed to find 'Number of platforms' in clinfo output."
324+
);
325+
}
326+
}
327+
328+
println!(
329+
"\x1b[32m[xtask]\x1b[0m OpenCL not detected. Installing OpenCL environment..."
330+
);
331+
332+
#[cfg(target_os = "windows")]
333+
{
334+
let download_status = std::process::Command::new("curl")
335+
.args(["-o", "w_opencl_runtime_p_2025.1.0.972.exe", "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/b6dccdb7-b503-41ea-bd4b-a78e9c2d8dd6/w_opencl_runtime_p_2025.1.0.972.exe"])
336+
.status();
337+
338+
if let Err(e) = download_status {
339+
println!(
340+
"\x1b[31m[xtask]\x1b[0m Failed to download w_opencl_runtime_p_2025.1.0.972: {}",
341+
e
342+
);
343+
println!("\x1b[33m[xtask]\x1b[0m You may need to enable proxy.");
344+
println!(
345+
"\x1b[33m[xtask]\x1b[0m You can also manually download from https://registrationcenter-download.intel.com/akdlm/IRC_NAS/b6dccdb7-b503-41ea-bd4b-a78e9c2d8dd6/w_opencl_runtime_p_2025.1.0.972.exe"
346+
);
347+
return;
348+
}
349+
350+
println!(
351+
"\x1b[33m[xtask]\x1b[0m Download completed. Please manually execute 'w_opencl_runtime_p_2025.1.0.972.exe' to install OpenCL for Intel CPU."
352+
);
353+
}
354+
#[cfg(not(target_os = "windows"))]
355+
{
356+
let has_cmd = |cmd: &str| {
357+
std::process::Command::new("sh")
358+
.arg("-c")
359+
.arg(format!("command -v {}", cmd))
360+
.stdout(std::process::Stdio::null())
361+
.status()
362+
.map(|s| s.success())
363+
.unwrap_or(false)
364+
};
365+
366+
if has_cmd("apt") {
367+
println!("\x1b[32m[xtask]\x1b[0m Installing opencl-headers...");
368+
let install_status = std::process::Command::new("sh")
369+
.arg("-c")
370+
.arg("sudo apt update && sudo apt install opencl-headers ocl-icd-opencl-dev -y")
371+
.status();
372+
373+
if let Err(e) = install_status {
374+
println!("\x1b[31m[xtask]\x1b[0m Failed to install OpenCL: {}", e);
375+
return;
376+
}
377+
378+
println!("\x1b[32m[xtask]\x1b[0m Installing Intel OpenCL runtime...");
379+
let setup_status = std::process::Command::new("sh")
380+
.arg("-c")
381+
.arg(
382+
"wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB \
383+
| gpg --dearmor | sudo tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null && \
384+
echo \"deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main\" | sudo tee /etc/apt/sources.list.d/oneAPI.list && \
385+
sudo apt update"
386+
)
387+
.status();
388+
389+
if let Err(e) = setup_status {
390+
println!(
391+
"\x1b[31m[xtask]\x1b[0m Failed to set up Intel OpenCL repository: {}",
392+
e
393+
);
394+
return;
395+
}
396+
397+
println!(
398+
"\x1b[33m[xtask]\x1b[0m Intel OpenCL runtime installation requires a proxy and may take time."
399+
);
400+
println!(
401+
"\x1b[33m[xtask]\x1b[0m Please manually execute the following command after enabling the proxy:"
402+
);
403+
println!(
404+
"\x1b[33m[xtask]\x1b[0m sudo apt install -y intel-oneapi-runtime-opencl"
405+
);
406+
} else {
407+
println!(
408+
"\x1b[31m[xtask]\x1b[0m Unsupported package manager. Please install OpenCL manually."
409+
);
410+
return;
411+
}
412+
}
413+
}
212414
_ => println!(
213-
"\x1b[32m[xtask]\x1b[0m Automatic installation for this environment is not supported: {env}"
415+
"\x1b[31m[xtask]\x1b[0m Automatic installation for this environment is not supported: {env}"
214416
),
215417
}
216418
}

0 commit comments

Comments
 (0)