name: lc_core
description: Core library: traits, types, logging, math, fiber, allocators, and STL containers.
LuisaCompute Core Library (lc_core)
Based on test cases in src/tests/unit/core/*.cpp.
Basic Traits
Header: <luisa/core/basic_traits.h>
Type Predicates
luisa::always_false_v<T...>
luisa::always_true_v<T...>
luisa::is_integral_v<T>
luisa::is_signed_integral_v<T>
luisa::is_vector_v<T> / is_vector_v<T,N> / is_vector2_v / is_vector3_v / is_vector4_v
luisa::is_boolean_vector_v<T>
luisa::is_signed_integral_vector_v<T>
luisa::is_matrix_v<T> / is_matrix_v<T,N> / is_matrix2_v / is_matrix3_v / is_matrix4_v
luisa::is_basic_v<T>
luisa::is_boolean_or_vector_v<T>
luisa::is_signed_integral_or_vector_v<T>
luisa::is_vector_same_dimension_v<T1, T2, ...>
Type Transformations
using Elem = luisa::vector_element_t<VecType>;
using Elem = luisa::matrix_element_t<MatType>;
auto val = luisa::to_underlying(Enum::Value);
constexpr size_t dim = luisa::vector_dimension_v<T>;
constexpr size_t dim = luisa::matrix_dimension_v<T>;
Basic Types
Header: <luisa/core/basic_types.h>
Aliases
luisa::byte(int8_t), ubyte(uint8_t), ushort(uint16_t), uint(uint32_t), ulong(uint64_t), slong(int64_t), half(16-bit)
Construction
float2 f(1.0f);
int2 i(1, 2);
auto z = float2::zero();
auto o = float2::one();
float2x2 m2;
float2x2 m2c(float2(1,2), float2(3,4));
auto eye = float2x2::eye(2.0f);
auto fill = float2x2::fill(3.0f);
Element Access
float3 v(1,2,3); v.x, v.y, v.z; v[0]; v[1] = 5.0f;
float3x3 m; m[0], m[1], m[2];
float e = m[col][row];
Operators
a+b, a-b, a*b, a/b
a*2.0f, 3.0f*a
-a, +a
~i, i<<1
a==b, a<b
b1||b2, b1&&b2
any(b), all(b), none(b)
m*2.0f, 3.0f*m, m/2.0f
m * v
a * b
a + b, a - b
Make Functions
make_float2(1.0f);
make_float2(1.0f, 2.0f);
make_float2(float3(1,2,3));
make_float3(float2(1,2), 3.0f);
make_float3(1.0f, float2(2,3));
make_float4(float2(1,2), float2(3,4));
make_float2x2(2.0f);
make_float2x2(1,2,3,4);
make_float2x2(float2(1,2), float2(3,4));
make_float3x3(1,2,3, 4,,, ,,);
(,,,, ,,,, ,,,, ,,,);
Binary File Stream
Header: <luisa/core/binary_file_stream.h>. Use instead of std::ifstream for binary I/O.
luisa::BinaryFileStream stream("file.bin");
if (stream.valid()) { }
size_t len = stream.length(), pos = stream.pos();
stream.set_pos(128); stream.set_pos(0);
stream.read(luisa::span<std::byte>(buf.data(), buf.size()));
stream.close();
luisa::BinaryFileStream s2(std::move(stream));
Binary IO (BinaryBlob)
Header: <luisa/core/binary_io.h>
luisa::BinaryBlob blob{ptr, size, [](void* p) { ::operator delete(p); }};
luisa::BinaryBlob empty;
std::byte* d = blob.data(); size_t sz = blob.size(); bool e = blob.empty();
luisa::span<std::byte> sp = static_cast<luisa::span<std::byte>>(blob);
luisa::BinaryBlob b2(std::move(blob)); b3 = std::move(b2);
void* raw = blob.release();
Clock
Header: <luisa/core/clock.h>
luisa::Clock clock;
clock.tic();
double ms = clock.toc();
double t1 = clock.toc();
Dynamic Module
Header: <luisa/core/dynamic_module.h>
auto mod = luisa::DynamicModule::load("name");
auto mod = luisa::DynamicModule::load("/path", "name");
auto mod = luisa::DynamicModule::load_exact("/path/lib.so");
if (mod) { void* h = mod.handle(); }
void* addr = mod.address("fn");
auto* fn = mod.function<MyFunc>("fn");
void* raw = mod.release(); luisa::dynamic_module_destroy(raw);
mod.reset();
luisa::DynamicModule::add_search_path(dir);
luisa::DynamicModule::remove_search_path(dir);
First Fit Allocator
Header: <luisa/core/first_fit.h>
luisa::FirstFit alloc(1024, 8);
luisa::FirstFit::Node* n = alloc.allocate(100);
if (n) { size_t off = n->offset(), sz = n->size(); }
n = alloc.allocate_best_fit(100);
alloc.free(n);
size_t sz = alloc.size(), align = alloc.alignment();
luisa::string fl = alloc.dump_free_list();
Logging
Header: <luisa/core/logging.h>
luisa::log_level_verbose();
luisa::log_flush();
luisa::log_verbose("msg"); luisa::log_info("v: {}", 42); luisa::log_warning("warn");
LUISA_VERBOSE("msg"); LUISA_INFO("v: {}, {}", 1, 2); LUISA_WARNING("warn");
LUISA_VERBOSE_WITH_LOCATION("dbg: {}", val);
LUISA_INFO_WITH_LOCATION("proc: {}", name);
LUISA_WARNING_WITH_LOCATION("deprecated: {}", api);
Format: {} (default), {:x} (hex), {:b} (binary), {:e} (scientific), {:.2f} (fixed precision).
Mathematics
Header: <luisa/core/mathematics.h>
Scalar
luisa::next_pow2(100u);
luisa::fract(3.7f);
luisa::radians(180.0f);
luisa::degrees(constants::pi);
luisa::sin(x), cos(x), sqrt(x), abs(x), min(a,b), max(a,b)
Vector (component-wise)
luisa::sin(v2), cos(v2), sqrt(v2), abs(v2), floor(v2), ceil(v2), fract(v2)
luisa::min(a, b), max(a, b), pow(a, b), atan2(y, x), fmod(a, b)
luisa::min(2.0f, a)
luisa::isnan(v2), isinf(v2)
luisa::dot(a, b);
luisa::length(a);
luisa::distance(a, b);
luisa::normalize(a);
luisa::cross(c, d);
Matrix
luisa::transpose(m);
luisa::inverse(m);
luisa::determinant(m);
luisa::translation(1,2,3);
luisa::scaling(2,3,4);
luisa::rotation(axis_float3, angle_rad);
Interpolation & Selection
luisa::select(false_val, true_val, cond);
luisa::lerp(a, b, t);
luisa::clamp(v, lo, hi);
luisa::sign(x);
luisa::fma(a, b, c);
Constants
luisa::constants::pi, pi_over_2, pi_over_4, two_pi, inv_pi, e
Pool Allocator
Header: <luisa/core/pool.h>
luisa::Pool<MyClass> pool;
luisa::Pool<MyClass, false> pool_nt;
MyClass* obj = pool.allocate();
pool.deallocate(obj);
MyClass* obj2 = pool.create();
MyClass* obj3 = pool.create(args...);
pool.destroy(obj2);
Fiber
Header: <luisa/core/fiber.h>. Built on marl.
Scheduler
luisa::fiber::scheduler sched;
luisa::fiber::scheduler sched(4);
Sync Primitives
luisa::fiber::event evt(luisa::fiber::event::Mode::Manual, false);
evt.signal(); evt.clear(); evt.wait(); bool r = evt.test()/evt.is_signalled();
luisa::fiber::counter cnt(3);
cnt.add(2); cnt.done(); cnt.wait();
luisa::fiber::mutex mtx;
luisa::fiber::lock lck(mtx);
luisa::fiber::condition_variable cv;
Tasks
luisa::fiber::schedule([]() noexcept { });
auto evt = luisa::fiber::async([]() noexcept { return 42; }); evt.wait();
Parallel For
luisa::fiber::parallel(100, [](uint32_t i) noexcept {});
luisa::fiber::parallel(100, [](uint32_t begin, uint32_t end) noexcept {});
auto cnt = luisa::fiber::async_parallel(100, [](uint32_t i) noexcept {}); cnt.wait();
luisa::fiber::parallel(data.begin(), data.end(), 64, [](auto l, auto r) {});
auto cnt = luisa::fiber::async_parallel(data.begin(), data.end(), 64, [](auto l, auto r) {}); cnt.wait();
luisa::fiber::counter cnt(0); luisa::fiber::async_parallel(cnt, 100, [](uint32_t i){});
luisa::fiber::parallel(1000, []{}, 10);
uint32_t n = luisa::fiber::worker_thread_count();
Defer
{ luisa_fiber_defer(printf("world\n")); printf("hello "); }
STL Containers & Utilities
Location: include/luisa/core/stl/. Uses std:: or EASTL based on LUISA_USE_SYSTEM_STL. All in luisa namespace.
Memory
Header: <luisa/core/stl/memory.h>
luisa::allocator<T> alloc;
auto sz1 = 64_k;
luisa::unique_ptr<T> up = luisa::make_unique<T>(args...);
luisa::shared_ptr<T> sp = luisa::make_shared<T>(args...);
luisa::weak_ptr<T> wp = sp;
luisa::span<T> s(data, count);
T* p = luisa::allocate_with_allocator<T>(n); luisa::deallocate_with_allocator(p);
T* obj = luisa::new_with_allocator<T>(args...); luisa::delete_with_allocator(obj);
auto u = luisa::bit_cast<uint32_t>(3.14f);
Strings & Format
Header: <luisa/core/stl/string.h>, <luisa/core/stl/format.h>
luisa::string s = "hello"; luisa::u8string u8s = u8"hello"; luisa::wstring ws = L"hello";
luisa::string_hash h; uint64_t hash = h("hello");
luisa::string s = luisa::format("Value: {}, {}", 42, 3.14);
auto s2 = luisa::to_string(float3(1,2,3));
auto hex = luisa::hash_to_string(0x1234ABCD);
Containers
luisa::vector<int> vec = {1,2,3}; vec.push_back(4);
luisa::fixed_vector<int, 64> fvec;
luisa::bitvector bits(100);
auto* raw = luisa::enlarge_by(vec, 10);
luisa::vector_resize(vec, 100);
size_t bytes = luisa::size_bytes(vec);
luisa::unordered_map<string, int> map; map.emplace("key", 42);
luisa::unordered_set<int> set;
luisa::map<string,int> omap; luisa::set<int> oset; luisa::multimap<string,int> mm; luisa::multiset<int> ms;
luisa::fixed_map<int,string,64> fmap; luisa::fixed_set<int,64> fset;
luisa::fixed_unordered_map<int,string,64> fumap; luisa::fixed_unordered_set<int,64> fus;
luisa::fixed_multimap<int,string,64> fmm; luisa::fixed_multiset<int,64> fms;
luisa::vector_map<int,string> vm; luisa::vector_set<> vs;
luisa::vector_multimap<,string> vmm; luisa::vector_multiset<> vms;
luisa::deque<> dq; luisa::queue<> q; luisa::stack<> st; luisa::priority_queue<> pq;
luisa::list<> lst; luisa::forward_list<> flst;
luisa::fixed_list<,> fl; luisa::fixed_forward_list<,> ffl;
luisa::ring_buffer<> rb; luisa::fixed_ring_buffer<,> frb;
LRU Cache
Header: <luisa/core/stl/lru_cache.h>
luisa::lru_cache<string, int> cache(100); cache.emplace("key", 42);
auto val = cache.at("key");
cache.touch("key");
auto tc = luisa::LRUCache<string, int>::create(100);
tc->set_delete_callback([](const int &v) {});
auto v = tc->fetch("key"); tc->update("key", 42);
Optional & Variant
Header: <luisa/core/stl/optional.h>, <luisa/core/stl/variant.h>
luisa::optional<int> opt = 42; if (opt) { int v = *opt; }
auto o = luisa::make_optional(3.14); auto n = luisa::nullopt;
luisa::variant<int,float,string> v = 3.14f;
if (luisa::holds_alternative<float>(v)) {}
auto f = luisa::get<float>(v);
auto p = luisa::get_if<int>(&v);
luisa::visit([](auto&& x){}, v);
Functional
Header: <luisa/core/stl/functional.h>
luisa::function<void(int)> fn = [](int){};
luisa::move_only_function<void(int)> mfn = [p=make_unique<int>()](int){};
luisa::less<> lt; luisa::equal_to<> eq; luisa::greater<> gt;
auto visitor = luisa::make_overloaded([](int i){ return "int"; }, [](float f){ return "float"; });
auto obj = luisa::lazy_construct([]{ return make_unique<Resource>(); });
auto guard = luisa::make_finally([]{ cleanup(); });
Hashing
Header: <luisa/core/stl/hash.h>
uint64_t h = luisa::hash_value(42);
uint64_t hc = luisa::hash_combine({h1, h2, h3});
luisa::Hash128 h128 = luisa::hash128(data, size, seed);
luisa::string s = h128.to_string();
Iterators & Algorithms
Header: <luisa/core/stl/iterator.h>, <luisa/core/stl/algorithm.h>
for (auto i : luisa::range(10)) {}
for (auto i : luisa::range(2, 10)) {}
for (auto i : luisa::range(0, 10, 2)) {}
luisa::sort(vec.begin(), vec.end());
luisa::sort(vec.begin(), vec.end(), luisa::greater<>{});
luisa::transform(a.begin(), a.end(), b.begin(), op);
bool found = luisa::binary_search(vec.begin(), vec.end(), val);
#include <luisa/core/stl/pdqsort.h>
pdqsort(vec.begin(), vec.end());
pdqsort_branchless(vec.begin(), vec.end());
Other
luisa::filesystem::path p = "/some/path"; luisa::string s = luisa::to_string(p);
luisa::stringstream ss; ss << "value=" << 42; luisa::string s = ss.str();
luisa::ostringstream oss; luisa::istringstream iss("42 3.14");
Summary
| Component | Header | Key |
|---|
| Basic Traits | <luisa/core/basic_traits.h> | is_vector_v, is_matrix_v, vector_element_t, to_underlying |
| Basic Types | <luisa/core/basic_types.h> | float2/3/4, float2x2/3x3/4x4, make_float2/3/4, make_float2x2/3x3/4x4 |
| Binary File Stream | <luisa/core/binary_file_stream.h> | BinaryFileStream |
| Binary IO | <luisa/core/binary_io.h> | BinaryBlob |
| Clock | <luisa/core/clock.h> | Clock::tic(), Clock::toc() |
| Dynamic Module | <luisa/core/dynamic_module.h> | DynamicModule::load(), address(), function<>() |
| First Fit | <luisa/core/first_fit.h> | FirstFit::allocate(), allocate_best_fit(), free() |
| Logging | <luisa/core/logging.h> | LUISA_INFO(), LUISA_WARNING(), log_level_info() |
| Mathematics | <luisa/core/mathematics.h> | sin(), dot(), normalize(), transpose(), inverse(), lerp(), clamp() |
| Pool | <luisa/core/pool.h> | Pool<T>::allocate(), create(), destroy() |
| Fiber | <luisa/core/fiber.h> | scheduler, , , , , , |