All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jcuda.Pointer Maven / Gradle / Ivy

There is a newer version: 12.0.0
Show newest version
/*
 * JCuda - Java bindings for NVIDIA CUDA driver and runtime API
 *
 * Copyright (c) 2009-2015 Marco Hutter - http://www.jcuda.org
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

package jcuda;
import java.nio.*;
import java.util.Arrays;


/**
 * A Java representation of a void pointer.
 */
public class Pointer extends NativePointerObject
{
    /**
     * The offset from the nativePointer, in bytes
     */
    private long byteOffset;

    /**
     * The buffer the pointer points to
     */
    private Buffer buffer;

    /**
     * The array of NativePointerObjects this pointer points to
     */
    private NativePointerObject pointers[];


    /**
     * Creates a new Pointer to the given values.
     *
     * @param values The values the pointer should point to
     * @return The pointer
     */
    public static Pointer to(byte values[])
    {
        return new Pointer(ByteBuffer.wrap(values));
    }

    /**
     * Creates a new Pointer to the given values.
     * The values may not be null.
     *
     * @param values The values the pointer should point to
     * @return The pointer
     */
    public static Pointer to(char values[])
    {
        return new Pointer(CharBuffer.wrap(values));
    }

    /**
     * Creates a new Pointer to the given values.
     * The values may not be null.
     *
     * @param values The values the pointer should point to
     * @return The pointer
     */
    public static Pointer to(short values[])
    {
        return new Pointer(ShortBuffer.wrap(values));
    }

    /**
     * Creates a new Pointer to the given values.
     * The values may not be null.
     *
     * @param values The values the pointer should point to
     * @return The pointer
     */
    public static Pointer to(int values[])
    {
        return new Pointer(IntBuffer.wrap(values));
    }

    /**
     * Creates a new Pointer to the given values.
     * The values may not be null.
     *
     * @param values The values the pointer should point to
     * @return The pointer
     */
    public static Pointer to(float values[])
    {
        return new Pointer(FloatBuffer.wrap(values));
    }

    /**
     * Creates a new Pointer to the given values.
     * The values may not be null.
     *
     * @param values The values the pointer should point to
     * @return The pointer
     */
    public static Pointer to(long values[])
    {
        return new Pointer(LongBuffer.wrap(values));
    }

    /**
     * Creates a new Pointer to the given values.
     * The values may not be null.
     *
     * @param values The values the pointer should point to
     * @return The pointer
     */
    public static Pointer to(double values[])
    {
        return new Pointer(DoubleBuffer.wrap(values));
    }

    /**
     * NOTE: This method does not take into account the position
     * and array offset of the given buffer. In order to create a
     * pointer that takes the position and array offset into account,
     * use the {@link #toBuffer(Buffer)} method. 
*
* * If the given buffer has a backing array, then the returned * pointer will in any case point to the start of the array, * even if the buffer has been created using the slice * method (like {@link ByteBuffer#slice()}). If the buffer is * direct, then this method will return a Pointer to the address * of the direct buffer. If the buffer has been created using the * slice method, then this will be the actual start * of the slice. Although this implies a different treatment of * direct- and non direct buffers, the method is kept for * backward compatibility.
*
* In both cases, for direct and array-based buffers, this method * does not take into account the position of the given buffer.
*
* The buffer must not be null, and either be a direct buffer, or * have a backing array * * @param buffer The buffer the pointer should point to * @return The pointer * @throws IllegalArgumentException If the given buffer * is null or is neither direct nor has a backing array */ public static Pointer to(Buffer buffer) { if (buffer == null || (!buffer.isDirect() && !buffer.hasArray())) { throw new IllegalArgumentException( "Buffer may not be null and must have an array or be direct"); } return new Pointer(buffer); } /** * Creates a new Pointer to the given buffer.
*
* Note that this method takes into account the array offset and position * of the given buffer, in contrast to the {@link #to(Buffer)} method. * * @param buffer The buffer * @return The new pointer * @throws IllegalArgumentException If the given buffer * is null or is neither direct nor has a backing array */ public static Pointer toBuffer(Buffer buffer) { if (buffer == null || (!buffer.isDirect() && !buffer.hasArray())) { throw new IllegalArgumentException( "Buffer may not be null and must have an array or be direct"); } if (buffer instanceof ByteBuffer) { return computePointer((ByteBuffer)buffer); } if (buffer instanceof ShortBuffer) { return computePointer((ShortBuffer)buffer); } if (buffer instanceof IntBuffer) { return computePointer((IntBuffer)buffer); } if (buffer instanceof LongBuffer) { return computePointer((LongBuffer)buffer); } if (buffer instanceof FloatBuffer) { return computePointer((FloatBuffer)buffer); } if (buffer instanceof DoubleBuffer) { return computePointer((DoubleBuffer)buffer); } throw new IllegalArgumentException( "Unknown buffer type: "+buffer); } /** * Creates a new Pointer to the given buffer, taking into * account the position and array offset of the given buffer. * The buffer is assumed to be non-null, and * be either direct or have a backing array. * * @param buffer The buffer * @return The pointer */ private static Pointer computePointer(ByteBuffer buffer) { Pointer result = null; if (buffer.isDirect()) { int oldPosition = buffer.position(); buffer.position(0); result = Pointer.to(buffer.slice()).withByteOffset( oldPosition * Sizeof.BYTE); buffer.position(oldPosition); } else if (buffer.hasArray()) { ByteBuffer t = ByteBuffer.wrap(buffer.array()); int elementOffset = buffer.position() + buffer.arrayOffset(); result = Pointer.to(t).withByteOffset( elementOffset * Sizeof.BYTE); } return result; } /** * Creates a new Pointer to the given buffer, taking into * account the position and array offset of the given buffer. * The buffer is assumed to be non-null, and * be either direct or have a backing array. * * @param buffer The buffer * @return The pointer */ private static Pointer computePointer(ShortBuffer buffer) { Pointer result = null; if (buffer.isDirect()) { int oldPosition = buffer.position(); buffer.position(0); result = Pointer.to(buffer.slice()).withByteOffset( oldPosition * Sizeof.SHORT); buffer.position(oldPosition); } else if (buffer.hasArray()) { ShortBuffer t = ShortBuffer.wrap(buffer.array()); int elementOffset = buffer.position() + buffer.arrayOffset(); result = Pointer.to(t).withByteOffset( elementOffset * Sizeof.SHORT); } return result; } /** * Creates a new Pointer to the given buffer, taking into * account the position and array offset of the given buffer. * The buffer is assumed to be non-null, and * be either direct or have a backing array. * * @param buffer The buffer * @return The pointer */ private static Pointer computePointer(IntBuffer buffer) { Pointer result = null; if (buffer.isDirect()) { int oldPosition = buffer.position(); buffer.position(0); result = Pointer.to(buffer.slice()).withByteOffset( oldPosition * Sizeof.INT); buffer.position(oldPosition); } else if (buffer.hasArray()) { IntBuffer t = IntBuffer.wrap(buffer.array()); int elementOffset = buffer.position() + buffer.arrayOffset(); result = Pointer.to(t).withByteOffset( elementOffset * Sizeof.INT); } return result; } /** * Creates a new Pointer to the given buffer, taking into * account the position and array offset of the given buffer. * The buffer is assumed to be non-null, and * be either direct or have a backing array. * * @param buffer The buffer * @return The pointer */ private static Pointer computePointer(LongBuffer buffer) { Pointer result = null; if (buffer.isDirect()) { int oldPosition = buffer.position(); buffer.position(0); result = Pointer.to(buffer.slice()).withByteOffset( oldPosition * Sizeof.LONG); buffer.position(oldPosition); } else if (buffer.hasArray()) { LongBuffer t = LongBuffer.wrap(buffer.array()); int elementOffset = buffer.position() + buffer.arrayOffset(); result = Pointer.to(t).withByteOffset( elementOffset * Sizeof.LONG); } return result; } /** * Creates a new Pointer to the given buffer, taking into * account the position and array offset of the given buffer. * The buffer is assumed to be non-null, and * be either direct or have a backing array. * * @param buffer The buffer * @return The pointer */ private static Pointer computePointer(FloatBuffer buffer) { Pointer result = null; if (buffer.isDirect()) { int oldPosition = buffer.position(); buffer.position(0); result = Pointer.to(buffer.slice()).withByteOffset( oldPosition * Sizeof.FLOAT); buffer.position(oldPosition); } else if (buffer.hasArray()) { FloatBuffer t = FloatBuffer.wrap(buffer.array()); int elementOffset = buffer.position() + buffer.arrayOffset(); result = Pointer.to(t).withByteOffset( elementOffset * Sizeof.FLOAT); } return result; } /** * Creates a new Pointer to the given buffer, taking into * account the position and array offset of the given buffer. * The buffer is assumed to be non-null, and * be either direct or have a backing array. * * @param buffer The buffer * @return The pointer */ private static Pointer computePointer(DoubleBuffer buffer) { Pointer result = null; if (buffer.isDirect()) { int oldPosition = buffer.position(); buffer.position(0); result = Pointer.to(buffer.slice()).withByteOffset( oldPosition * Sizeof.DOUBLE); buffer.position(oldPosition); } else if (buffer.hasArray()) { DoubleBuffer t = DoubleBuffer.wrap(buffer.array()); int elementOffset = buffer.position() + buffer.arrayOffset(); result = Pointer.to(t).withByteOffset( elementOffset * Sizeof.DOUBLE); } return result; } /** * Creates a new Pointer to the given Pointers. The array * of pointers may not be null, and may not * contain null elements. * * @param pointers The pointers the pointer should point to * @return The new pointer * @throws IllegalArgumentException If the given array * is null */ public static Pointer to(NativePointerObject ... pointers) { if (pointers == null) { throw new IllegalArgumentException( "Pointer may not point to null objects"); } return new Pointer(pointers); } /** * Creates a new (null) Pointer */ public Pointer() { buffer = null; pointers = null; byteOffset = 0; } /** * Constructor which accepts a constant value as the pointer value. * Solely for the constant pointer instances in the JCudaDriver * class, to create the CU_LAUNCH_PARAM_END, * CU_LAUNCH_PARAM_BUFFER_POINTER, and CU_LAUNCH_PARAM_BUFFER_SIZE * pointer constants. * * @param nativePointerValue The native pointer value */ protected Pointer(long nativePointerValue) { super(nativePointerValue); buffer = null; pointers = null; byteOffset = 0; } /** * Creates a Pointer to the given Buffer * * @param buffer The buffer to point to */ private Pointer(Buffer buffer) { this.buffer = buffer; pointers = null; byteOffset = 0; } /** * Creates a Pointer to the given array of pointers * * @param pointers The array the pointer points to */ private Pointer(NativePointerObject pointers[]) { buffer = null; this.pointers = pointers; byteOffset = 0; } /** * Copy constructor * * @param other The other Pointer */ protected Pointer(Pointer other) { super(other.getNativePointer()); this.buffer = other.buffer; this.pointers = other.pointers; this.byteOffset = other.byteOffset; } /** * Creates a copy of the given pointer, with an * additional byte offset * * @param other The other pointer * @param byteOffset The additional byte offset */ protected Pointer(Pointer other, long byteOffset) { this(other); this.byteOffset += byteOffset; } /** * Returns a new pointer with an offset of the given number * of bytes * * @param byteOffset The byte offset for the pointer * @return The new pointer with the given byte offset */ public Pointer withByteOffset(long byteOffset) { return new Pointer(this, byteOffset); } /** * Returns a ByteBuffer that corresponds to the specified * segment of the memory that this pointer points to.
*
* The returned byte buffer will have the byte order that is implied * by ByteOrder#nativeOrder(). It will be a slice of the * buffer that is stored internally. So it will share the same memory, * but its position and limit will be independent of the internal buffer. *
* This function may only be applied to pointers that have been set to * point to a region of host- or unified memory using one of these * methods: *
    *
  • {@link jcuda.driver.JCudaDriver#cuMemAllocHost}
  • *
  • {@link jcuda.driver.JCudaDriver#cuMemHostAlloc}
  • *
  • {@link jcuda.driver.JCudaDriver#cuMemAllocManaged}
  • *
  • {@link jcuda.runtime.JCuda#cudaMallocHost}
  • *
  • {@link jcuda.runtime.JCuda#cudaHostAlloc}
  • *
  • {@link jcuda.runtime.JCuda#cudaMallocManaged}
  • *
  • {@link Pointer#to(byte[])}
  • *
*
* For other pointer types, null is returned. * * @param byteOffset The offset in bytes * @param byteSize The size of the byte buffer, in bytes * @return The byte buffer * @throws IllegalArgumentException If the byteOffset and * byteSize describe an invalid memory range (for example, * when the byteOffset is negative) * @throws ArithmeticException If the byteOffset or * byteOffset + byteSize overflows an int. */ public ByteBuffer getByteBuffer(long byteOffset, long byteSize) { if (buffer == null) { return null; } if (!(buffer instanceof ByteBuffer)) { return null; } ByteBuffer internalByteBuffer = (ByteBuffer)buffer; ByteBuffer byteBuffer = internalByteBuffer.slice(); byteBuffer.limit(Math.toIntExact(byteOffset + byteSize)); byteBuffer.position(Math.toIntExact(byteOffset)); return byteBuffer.slice().order(ByteOrder.nativeOrder()); } /** * Returns a ByteBuffer that corresponds to the memory that this * pointer points to.
*
* The returned byte buffer will have the byte order that is implied * by ByteOrder#nativeOrder(). It will be a slice of the * buffer that is stored internally. So it will share the same memory, * but its position and limit will be independent of the internal buffer. *
* This function may only be applied to pointers that have been set to * point to a region of host- or unified memory using one of these * methods: *
    *
  • {@link jcuda.driver.JCudaDriver#cuMemAllocHost}
  • *
  • {@link jcuda.driver.JCudaDriver#cuMemHostAlloc}
  • *
  • {@link jcuda.driver.JCudaDriver#cuMemAllocManaged}
  • *
  • {@link jcuda.runtime.JCuda#cudaMallocHost}
  • *
  • {@link jcuda.runtime.JCuda#cudaHostAlloc}
  • *
  • {@link jcuda.runtime.JCuda#cudaMallocManaged}
  • *
  • {@link Pointer#to(byte[])}
  • *
*
* For other pointer types, null is returned. * * @return The byte buffer */ public ByteBuffer getByteBuffer() { if (buffer == null) { return null; } if (!(buffer instanceof ByteBuffer)) { return null; } ByteBuffer internalByteBuffer = (ByteBuffer)buffer; ByteBuffer byteBuffer = internalByteBuffer.slice(); return byteBuffer.order(ByteOrder.nativeOrder()); } /** * Returns the byte offset * * @return The byte offset */ protected long getByteOffset() { return byteOffset; } /** * Returns a String representation of this object. * * @return A String representation of this object. */ @Override public String toString() { if (buffer != null) { return "Pointer["+ "buffer="+buffer+","+ "byteOffset="+byteOffset+"]"; } else if (pointers != null) { return "Pointer["+ "pointers="+Arrays.toString(pointers)+","+ "byteOffset="+byteOffset+"]"; } else { return "Pointer["+ "nativePointer=0x"+Long.toHexString(getNativePointer())+","+ "byteOffset="+byteOffset+"]"; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy