Skip to content

Implement mlx.core.recv_like() #256

@sydneyrenee

Description

@sydneyrenee

🎯 Implement mlx.core.recv_like()

Priority: low | Module: distributed_ops | Type: other | Category: distributed_ops


📋 Quick Reference

Item Value
Python Source python/src/ops.cpp
Node Target node/src/native/array.cc
Test File node/test/ops.test.js
C++ Namespace mlx::core

🚀 Step-by-Step Implementation

Step 1: Review Python Implementation

# See the Python binding
grep -B 5 -A 30 '"recv_like"' python/src/ops.cpp

Step 2: Implement in Node.js

File to edit: node/src/native/array.cc

Napi::Value RecvLike(const Napi::CallbackInfo& info) {
  auto env = info.Env();
  auto* addon = static_cast<mlx::node::AddonData*>(info.Data());
  
  try {
    mlx::node::Runtime::Instance().EnsureMetalInit();
  } catch (const std::exception& e) {
    Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
    return env.Null();
  }
  
  // TODO: Parse arguments based on Python signature
  // Check python/src/python/src/ops.cpp for the exact signature
  
  // Example: Parse array argument
  auto* wrapper = UnwrapArray(env, info[0]);
  if (!wrapper) return env.Null();
  const auto& a = wrapper->tensor();
  
  // Parse stream
  auto stream = mlx::core::default_stream(mlx::core::default_device());
  // (adjust index based on number of args)
  if (info.Length() > 1) {
    stream = mlx::node::ParseStreamOrDevice(env, info[info.Length() - 1], *addon);
    if (env.IsExceptionPending()) return env.Null();
  }
  
  try {
    auto result = mlx::core::recv_like(/* args */, stream);
    return WrapArray(env, std::make_shared<mlx::core::array>(std::move(result)));
  } catch (const std::exception& e) {
    Napi::Error::New(env, std::string("recv_like failed: ") + e.what())
        .ThrowAsJavaScriptException();
    return env.Null();
  }
}

Step 3: Register the Function

Add to the Init() function at bottom of node/src/native/array.cc:

core.Set("recv_like", Napi::Function::New(env, RecvLike, "recv_like", &data));

Step 4: Add Tests

File: node/test/ops.test.js

const mx = require('..');

describe('mlx.core.recv_like', () => {
  it('should work correctly', () => {
    // TODO: Add test based on Python tests
    // const a = mx.core.array([1, 2, 3]);
    // const result = mx.distributed_ops.recv_like(a);
    // expect(result).toBeDefined();
  });
});

📚 Resources

Similar Implementations

Look at these in node/src/native/array.cc:

  • Unary ops: Exp(), Log(), Sin(), Cos()
  • Binary ops: Add(), Multiply(), Subtract()
  • Reductions: Sum(), Mean(), Max(), Min()

Common Patterns

Parse Array:

auto* wrapper = UnwrapArray(env, info[0]);
if (!wrapper) return env.Null();
const auto& a = wrapper->tensor();

Parse Stream:

auto stream = mlx::core::default_stream(mlx::core::default_device());
if (info.Length() > N) {
  stream = mlx::node::ParseStreamOrDevice(env, info[N], *addon);
}

Return Array:

return WrapArray(env, std::make_shared<mlx::core::array>(std::move(result)));

✅ Completion Checklist

  • Reviewed Python implementation
  • Implemented function in node/src/native/array.cc
  • Registered in Init()
  • Added tests in node/test/ops.test.js
  • Builds: cd node && npm run build
  • Tests pass: npm test
  • Updated docs/API_CHECKLIST.md

Auto-generated for MLX Node.js API completeness

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions