How to compile nvptx in Rust - rust

I have tried to compile nvptx in Rust with the help of this site. Here is the code I wrote.
use std::time::Duration;
use std::thread::sleep;
#[cfg(target_arch="nvptx")]
fn foo() {
println!("call");
use std::arch::nvptx::*;
unsafe {
let c = malloc(10);
sleep(Duration::from_millis(100000));
free(c);
}
}
fn main() {
#[cfg(target_arch="nvptx")]
foo();
println!("Hello, world!");
}
I've done my research.
I thought it might be possible to compile to nvptx by doing cargo run --target nvptx64-nvidia-cuda. However, when I tried to run it, I received the following error.
error[E0463]: can't find crate for `std`.
|.
= note: the `nvptx64-nvidia-cuda` target may not be installed
error: aborting due to previous error
For more information about this error, try `rustc --explain E0463`.
error: could not compile `core_nvptx`.
To learn more, run the command again with --verbose.
So, I set rust to nightly and added a target for nvptx.
rustup target add nvptx64-nvidia-cuda.
So we added
cargo run --target nvptx64-nvidia-cuda.
I received the same error as above when I did
postscript
I have created a separate nvptx crate with the following file structure.
├─ Cargo.lock
├─ Cargo.toml
├─ nvptx
│ ├─ Cargo.lock
│ ├─ Cargo.toml
└─ src
└─ lib.rs
r└─ src
r└─ main.rs
I created a .cargo/config file in the nvptx crate.
In it, I wrote the following
[build].
target = "nvptx64-nvidia-cuda".
And here is how the contents of nvptx/src/lib.rs looks
#! [feature(stdsimd)]
#! [no_std] #!
use core::arch::nvptx;
use core::ffi::c_void;
unsafe fn cuda_alloc(size: usize) -> *mut c_void {
nvptx::malloc(size)
}
unsafe fn cuda_free(ptr: *mut c_void) {
nvptx::free(ptr);
}
Also, the code in src/main.rs is as follows.
use std::time::Duration;
use std::thread::sleep;
use nvptx::*;
fn foo() {
println!("call");
unsafe {
let ptr = cuda_alloc(10 as usize);
cuda_free(ptr);
}
}
fn main() {
foo();
println!("Hello, world!");
}
When I compiled this, I received the following error.
error[E0432]: unresolved import `core::arch::nvptx`
--> nvptx/src/lib.rs:4:5
| use core::arch::nvptx
4 | use core::arch::nvptx;
| ^^^^^^^^^^^^^^^^^ no `nvptx` in `arch`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0432`.
error: could not compile `nvptx`.
To learn more, run the command again with --verbose.
Rust version:
nightly-x86_64-unknown-linux-gnu (default)
rustc 1.54.0-nightly (f94942d84 2021-05-19)

Related

Failed to resolve module with a use statement, but the module can be used when specifying scope

In Rust, I have the following folder structure:
├── Cargo.toml
└── src
├── bin
│ └── main.rs
└── lib.rs
This is as recommended in this answer.
This is the (relevant) contents of the Cargo.toml file:
[package]
name = "devinit"
...
And this is the contents of my lib.rs file:
pub mod testmod {
pub fn testfunc() {
println!("Hello world");
}
}
When trying to use the function testfunc() in main.rs, I can refer to it by specifying its scope:
fn main() {
devinit::testmod::testfunc();
}
This compiles and executes successfully. However, if I were to actually 'use' it, as seen below...
use devinit::testmod::testfunc;
fn main() {
testfunc();
}
...the compilation fails. The following code fails to compile with the error 'failed to resolve: maybe a missing crate `devinit`?'
Why is this happening? Looking at the aforementioned answer's author's project (linked in previous edits of the answer), the structure seems to be the same...
I'm pretty new to Rust, so maybe I missed something?

structopt unable to find its Args parser when defined in a separate file

I'm starting on a command-line tool in Rust, and hitting a wall right from the get-go. I can parse command-line arguments using StructOpt if the Opt struct is defined in main.rs, but since I want to be able to pass the Opt struct into the library code, I'm defining it in its own file so that other parts of the library know what it's all about.
Here's the version of the code that's dumping the fewest errors, although I concede that it's largely cobbled together by trying things suggested by the compiler and some random SO suggestions, so it may be completely wrong.
The build error I'm getting is:
$ cargo run
Compiling basic v0.1.0 (/home/mpalmer/src/action-validator/blobble)
error[E0433]: failed to resolve: maybe a missing crate `structopt`?
--> src/opt.rs:8:5
|
8 | /// Activate debug mode
| ^^^^^^^^^^^^^^^^^^^^^^^ not found in `structopt::clap`
|
help: consider importing this struct
|
3 | use opt::structopt::clap::Arg;
|
For more information about this error, try `rustc --explain E0433`.
error: could not compile `basic` due to previous error
$ cargo --version
cargo 1.56.0 (4ed5d137b 2021-10-04)
$ rustc --version
rustc 1.56.0 (09c42c458 2021-10-18)
(Yes, I have tried adding use opt::structopt::clap::Arg;, just in case, but the error doesn't go away and I get a warning about an unused import -- while still being told to try adding the same use that is unused, which is amusing)
Cargo.toml
[package]
name = "basic"
version = "0.1.0"
authors = ["User"]
[dependencies]
structopt = "0.3"
src/main.rs
extern crate basic;
extern crate structopt;
use basic::Opt;
use structopt::StructOpt;
fn main() {
let opt = Opt::from_args();
println!("{:#?}", opt)
}
src/lib.rs
mod opt;
pub use crate::opt::Opt;
src/opt.ts
extern crate structopt;
use self::structopt::StructOpt;
#[derive(StructOpt, Debug)]
#[structopt(name = "basic")]
pub struct Opt {
/// Activate debug mode
#[structopt(short,long)]
debug: bool,
}
Suggestions gratefully appreciated.
A working version is
Cargo.toml
[package]
name = "basic"
version = "0.1.0"
authors = ["User"]
edition = "2018"
[dependencies]
structopt = "0.3"
lib.rs
#[macro_use] extern crate structopt;
use structopt::StructOpt;
pub mod opt;
opt.rs
#[derive(StructOpt, Debug)]
#[structopt(name = "basic")]
pub struct Opt {
/// Activate debug mode
#[structopt(short,long)]
debug: bool,
}
main.rs
#[macro_use] extern crate structopt;
use structopt::StructOpt;
fn main() {
let opt = basic::opt::Opt::from_args();
println!("{:#?}", opt);
}
You need to declare use structopt::StructOpt because from_args trait must be in the scope.

How do I access files in the src directory from files in my tests directory?

I have a project layout that looks like the following:
src/
int_rle.rs
lib.rs
tests/
test_int_rle.rs
The project compiles with cargo build, but I am unable to run the test with cargo test. I get the error
error[E0432]: unresolved import `int_rle`. There is no `int_rle` in the crate root
--> tests/test_int_rle.rs:1:5
|
1 | use int_rle;
| ^^^^^^^
error[E0433]: failed to resolve. Use of undeclared type or module `int_rle`
--> tests/test_int_rle.rs:7:9
|
7 | int_rle::IntRle { values: vec![1, 2, 3] }
| ^^^^^^^^^^^^^^^ Use of undeclared type or module `int_rle`
error: aborting due to 2 previous errors
error: Could not compile `minimal_example_test_directories`.
My code:
// src/lib.rs
pub mod int_rle;
// src/int_rle.rs
#[derive(Debug, PartialEq)]
pub struct IntRle {
pub values: Vec<i32>,
}
// tests/test_int_rle.rs
use int_rle;
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
int_rle::IntRle { values: vec![1, 2, 3] }
}
}
// Cargo.toml
[package]
name = "minimal_example_test_directories"
version = "0.1.0"
authors = ["Johann Gambolputty de von Ausfern ... von Hautkopft of Ulm"]
[dependencies]
Related: How do I compile a multi-file crate in Rust? (how to do it if the test and source files are in the same folder.)
The files src/int_rle.rs and src/lib.rs form your library, and together are called a crate.
Your tests and examples folders are not considered part of the crate. This is good, because when someone uses your library, they don't need your tests, they just need your library.
You can fix your issue by adding the line extern crate minimal_example_test_directories; to the top of tests/test_int_rle.rs.
You can read more about Rust's crate and module structure in the book, here.
This should be a working version of your test file:
// tests/test_int_rle.rs
extern crate minimal_example_test_directories;
pub use minimal_example_test_directories::int_rle;
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
super::int_rle::IntRle { values: vec![1, 2, 3] };
}
}

How to access a symbol defined in nested module?

I am using rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14)
src
├── main.rs
└── core
├── mod.rs
└── expressionType.rs
main.rs:
mod core;
use core::expressionType;
fn main() {
let t = expressionType::ExpressionType.Integer;
println!("Hello, world!")
}
expressionType.rs:
pub enum ExpressionType {
Integer,
List(Box<ExpressionType>),
Function(Box<ExpressionType>, Box<ExpressionType>)
}
mod.rs:
pub mod expressionType;
from src, when I try to do rustc main.rs, I get
main.rs:5:13: 5:43 error: unresolved name `expressionType::ExpressionType`
main.rs:5 let t = expressionType::ExpressionType.Integer;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
I also tried core::expressionType::ExpressionType and expressionType.ExpressionType
Am I missing something? Why can't I access enum from expressionType.rs
UPD1: I also tried to add
pub use self::expressionType::ExpressionType;
to mod.rs, but after that in main.rs neither core::ExpressionType, nor expressionType::ExpressionType become available.
You need to write ExpressionType::Integer rather than ExpressionType.Integer (:: instead of .). In the latter case, the compiler is looking for a value, such as a variable or constant, named ExpressionType.

How can I use shared logic from different files?

Having shared logic in:
// euler/shared/lib.rs
pub fn foo() {
println!("shared::foo()");
}
How can I use it from different files:
// euler/001/main.rs
use super::shared; // error: unresolved import `super::shared`
fn main() {
shared::foo(); // how to access it?
}
// euler/002/main.rs
use super::shared; // error: unresolved import `super::shared`
fn main() {
shared::foo(); // how to access it?
}
mdup's answer is correct, but I'd encourage you to use Cargo, Rust's package manager. It will do two very important things for you here:
Set up the correct command line arguments to rustc.
Automatically rebuild the dependent libraries when they change.
Use cargo new shared and cargo new --bin euler-001 to generate the right directory structure. Move your shared code to shared/src/lib.rs and your binaries to euler-001/src/main.rs:
.
├── euler-001
│   ├── Cargo.toml
│   └── src
│   └── main.rs
└── shared
├── Cargo.toml
└── src
└── lib.rs
Then, edit euler-001/Cargo.toml and add the dependencies section:
[dependencies.shared]
path = "../shared"
And tweak your main.rs to know about the crate:
extern crate shared;
fn main() {
shared::foo();
}
Now, you can simply type cargo run in the euler-001 directory:
$ cargo run
Compiling shared v0.1.0 (file:///private/tmp/play/euler-001)
Compiling euler-001 v0.1.0 (file:///private/tmp/play/euler-001)
Running `target/debug/euler-001`
shared::foo()
Note that you don't have to remember command line arguments and things are compiled for you! Having a built-in package manager is great!
One solution is to create a library out of the shared code. This will allow you to use an extern crate declaration.
// euler/shared/shared.rs
pub fn foo() {
println!("shared::foo()");
}
To compile the lib:
$ cd euler/shared
$ rustc --crate-type=lib shared.rs
$ ls -l libshared.rlib
-rw-r--r-- 1 mdup wheel 6758 May 17 14:38 libshared.rlib
Here is how you use it in "client" code:
// euler/001/main.rs
extern crate shared;
fn main() {
shared::foo();
}
The compile the client:
$ cd euler/001
$ rustc -L ../shared main.rs
$ ls -l main
-rwxr-xr-x 1 mdup wheel 291420 May 17 14:42 main
$ ./main
shared::foo()
More info in Rust By Example, section "Crates", pages "Library" and "extern crate".

Resources