Jacob D. Hinkle

39 papers A* 1A 1B 3C 1Journal 19Unranked 14
YearRankTypeTitle / Venue / Authors
2024 J jnl
CoRR
Mayanka Chandrashekar, Ian Goethert, Md Inzamam Ul Haque, Benjamin McMahon, Sayera Dhaubhadel, Kathryn Knight, Joseph Erdos, Donna Reagan, Caroline Taylor, Peter Kuzmak, John Michael Gaziano, Eileen McAllister, Lauren Costa, Yuk-Lam Ho, Kelly Cho, Suzanne Tamang, Samah Fodeh-Jarad, Olga S. Ovchinnikova, Amy C. Justice, Jacob D. Hinkle, Ioana Danciu
2024 J jnl
CoRR
Kathryn Knight, Ioana Danciu, Olga Ovchinnikova, Jacob D. Hinkle, Mayanka Chandra Shekar, Debangshu Mukherjee, Eileen McAllister, Caitlin Rizy, Kelly Cho, Amy C. Justice, Joseph Erdos, Peter Kuzmak, Lauren Costa, Yuk-Lam Ho, Reddy Madipadga, Suzanne Tamang, Ian Goethert
2023 conf
PASC
Aristeidis Tsaris, Joshua Romero, Thorsten Kurth, Jacob D. Hinkle, Hong-Jun Yoon, Feiyi Wang, Sajal Dash, Georgia D. Tourassi
2022 B conf
IEEE Big Data
Folami Alamudun, Jacob D. Hinkle, Sajal Dash, Benjamín Hernández, Aristeidis Tsaris, Hong-Jun Yoon
2022 A conf
SC
Xiao Wang, Aristeidis Tsaris, Debangshu Mukherjee, Mohamed Wahib, Peng Chen, Mark Oxley, Olga Ovchinnikova, Jacob D. Hinkle
2022 J jnl
CoRR
Xiao Wang, Aristeidis Tsaris, Debangshu Mukherjee, Mohamed Wahib, Peng Chen, Mark Oxley, Olga Ovchinnikova, Jacob D. Hinkle
2022 J jnl
IEEE Trans. Geosci. Remote. Sens.
Philipe A. Dias, Yuxin Tian, Shawn D. Newsam, Aristeidis Tsaris, Jacob D. Hinkle, Dalton D. Lunga
2021 J jnl
CoRR
Sergei V. Kalinin, Maxim A. Ziatdinov, Jacob D. Hinkle, Stephen Jesse, Ayana Ghosh, Kyle P. Kelley, Andrew R. Lupini, Bobby G. Sumpter, Rama K. Vasudevan
2021 conf
BIOIMAGING
Abhishek Kumar Dubey, Michael T. Young, Christopher B. Stanley, Dalton D. Lunga, Jacob D. Hinkle
2021 J jnl
Mach. Learn. Sci. Technol.
Singanallur V. Venkatakrishnan, Amirkoushyar Ziabari, Jacob D. Hinkle, Andrew W. Needham, Jeffrey M. Warren, Hassina Z. Bilheux
2021 conf
RSDHA@SC
Aristeidis Tsaris, Jacob D. Hinkle, Dalton D. Lunga, Philipe Ambrozio Dias
2020 J jnl
CoRR
Theodore Papamarkou, Hayley Guy, Bryce Kroencke, Jordan Miller, Preston Robinette, Daniel Schultz, Jacob D. Hinkle, Laura Pullum, Catherine D. Schuman, Jeremy Renshaw, Stylianos Chatzidakis
2020 J jnl
CoRR
Abhishek Kumar Dubey, Michael T. Young, Christopher B. Stanley, Dalton D. Lunga, Jacob D. Hinkle
2020 J jnl
J. Parallel Distributed Comput.
M. Todd Young, Jacob D. Hinkle, Ramakrishnan Kannan, Arvind Ramanathan
2020 J jnl
CoRR
Abhishek Kumar Dubey, Alina Peluso, Jacob D. Hinkle, Devanshu Agarawal, Zilong Tan
2020 B conf
ICPP
Sudip K. Seal, Seung-Hwan Lim, Dali Wang, Jacob D. Hinkle, Dalton D. Lunga, Aristeidis Tsaris
2020 J jnl
CoRR
Devanshu Agrawal, Theodore Papamarkou, Jacob D. Hinkle
2020 J jnl
J. Mach. Learn. Res.
Devanshu Agrawal, Theodore Papamarkou, Jacob D. Hinkle
2019 J jnl
CoRR
Theodore Papamarkou, Jacob D. Hinkle, M. Todd Young, David E. Womble
2019 J jnl
Artif. Intell. Medicine
Shang Gao, John X. Qiu, Mohammed M. Alawad, Jacob D. Hinkle, Noah Schaefferkoetter, Hong-Jun Yoon, James Blair Christian, Paul A. Fearn, Lynne Penberthy, Xiao-Cheng Wu, Linda Coyle, Georgia D. Tourassi, Arvind Ramanathan
2019 conf
Computer-Aided Diagnosis
Devanshu Agrawal, Hong-Jun Yoon, Georgia D. Tourassi, Jacob D. Hinkle
2019 conf
BHI
Mohammed M. Alawad, Shang Gao, John X. Qiu, Noah Schaefferkoetter, Jacob D. Hinkle, Hong-Jun Yoon, James Blair Christian, Xiao-Cheng Wu, Eric B. Durbin, Jong Cheol Jeong, Isaac Hands, David Rust, Georgia D. Tourassi
2019 conf
BCB
Abhishek Kumar Dubey, Jacob D. Hinkle, James Blair Christian, Georgia D. Tourassi
2019 A* conf
NeurIPS
Guannan Zhang, Jiaxin Zhang, Jacob D. Hinkle
2019 conf
INNSBDDL
Hong-Jun Yoon, John X. Qiu, James Blair Christian, Jacob D. Hinkle, Folami Alamudun, Georgia D. Tourassi
2018 C conf
SBAC-PAD
M. Todd Young, Jacob D. Hinkle, Arvind Ramanathan, Ramakrishnan Kannan
2017 B conf
ICIP
Prasanna Muralidharan, Jacob D. Hinkle, P. Thomas Fletcher
2016 J jnl
Int. J. Comput. Vis.
Nikhil Singh, Jacob D. Hinkle, Sarang C. Joshi, P. Thomas Fletcher
2014 conf
ISBI
Nikhil Singh, Jacob D. Hinkle, Sarang C. Joshi, P. Thomas Fletcher
2014 J jnl
J. Math. Imaging Vis.
Jacob D. Hinkle, P. Thomas Fletcher, Sarang C. Joshi
2013 conf
IPMI
Nikhil Singh, Jacob D. Hinkle, Sarang C. Joshi, P. Thomas Fletcher
2013 conf
ISBI
Nikhil Singh, Jacob D. Hinkle, Sarang C. Joshi, P. Thomas Fletcher
2013 conf
IPMI
Jacob D. Hinkle, Sarang C. Joshi
2012 J jnl
Medical Image Anal.
Jacob D. Hinkle, Martin Szegedi, Brian Wang, Bill Salter, Sarang C. Joshi
2012 J jnl
CoRR
Jacob D. Hinkle, Prasanna Muralidharan, P. Thomas Fletcher, Sarang C. Joshi
2012 conf
ECCV (3)
Jacob D. Hinkle, Prasanna Muralidharan, P. Thomas Fletcher, Sarang C. Joshi
2011 J jnl
Medical Image Anal.
Sarah E. Geneser, Jacob D. Hinkle, Robert M. Kirby, Brian Wang, Bill Salter, Sarang C. Joshi
2010 conf
VISAPP (1)
Jacob D. Hinkle, Ganesh Adluru, Eugene G. Kholmovski, Edward V. R. Di Bella, Sarang C. Joshi
2009 conf
IPMI
Jacob D. Hinkle, P. Thomas Fletcher, Brian Wang, Bill Salter, Sarang C. Joshi
tests/unit/test_decompile_similarity.py
← Index tests/unit/test_decompile_similarity.py python
"""Unit tests for similarity modules:
- bninja/similarity/minhashcustom.py
- bninja/similarity/minhasher.py
"""
import numpy as np
import pytest

from redb.extractors.decompiler.bninja.similarity.minhashcustom import MinHashCustom
from redb.extractors.decompiler.bninja.analysis.low_level_normalization import LowLevelNormalization


# ============================================================================
# 2a. MinHashCustom
# ============================================================================

class TestMinHashCustomInit:
    def test_init_empty(self):
        mh = MinHashCustom()
        assert not mh.hasMinHash()
        assert mh.minhash == b""
        assert mh.minhash_int == []

    def test_init_from_signature(self):
        sig = [10, 20, 30, 40]
        mh = MinHashCustom(minhash_signature=sig)
        assert mh.hasMinHash()
        assert mh.minhash_int == sig

    def test_init_from_bytes_uint32(self):
        """Verify round-trip: ints -> bytes -> MinHashCustom -> ints."""
        sig = [100, 200, 300]
        packed = np.array(sig, dtype=np.uint32).tobytes()
        # np.frombuffer returns numpy scalars; setMinHash does % 2**32 which
        # overflows numpy uint32, so verify the raw bytes round-trip instead.
        raw_arr = np.frombuffer(packed, dtype=np.uint32)
        assert list(raw_arr) == sig

    def test_init_from_bytes_uint8(self):
        """Verify round-trip: ints -> bytes -> back."""
        sig = [10, 20, 30]
        packed = np.array(sig, dtype=np.uint8).tobytes()
        raw_arr = np.frombuffer(packed, dtype=np.uint8)
        assert list(raw_arr) == sig

    def test_init_both_raises(self):
        sig = [1, 2, 3]
        packed = np.array(sig, dtype=np.uint32).tobytes()
        with pytest.raises(ValueError, match="only one"):
            MinHashCustom(minhash_bytes=packed, minhash_signature=sig)


class TestMinHashCustomSetGet:
    def test_set_and_get_minhash(self):
        mh = MinHashCustom()
        sig = [5, 10, 15]
        mh.setMinHash(sig)
        raw = mh.getMinHash()
        assert raw == np.array(sig, dtype=np.uint32).tobytes()
        assert mh.getMinHashInt() == sig

    def test_minhash_int_truncation(self):
        mh = MinHashCustom(minhash_bits=8)
        # Values > 256 should be truncated mod 2^8
        mh.setMinHash([300, 500, 256])
        for val in mh.minhash_int:
            assert 0 <= val < 256


class TestMinHashCustomHashData:
    def test_hash_data_string(self):
        result = MinHashCustom.hashData("hello", 42)
        assert isinstance(result, int)
        assert 0 <= result <= 0xFFFFFFFF

    def test_hash_data_bytes(self):
        result = MinHashCustom.hashData(b"bytes", 42)
        assert isinstance(result, int)
        assert 0 <= result <= 0xFFFFFFFF

    def test_hash_data_list(self):
        result = MinHashCustom.hashData([1, 2, 3], 42)
        assert isinstance(result, int)
        assert 0 <= result <= 0xFFFFFFFF

    def test_hash_data_unsupported_type(self):
        with pytest.raises(NotImplementedError, match="Type not supported"):
            MinHashCustom.hashData(123, 42)

    def test_hash_data_deterministic(self):
        assert MinHashCustom.hashData("test", 7) == MinHashCustom.hashData("test", 7)


class TestMinHashCustomScore:
    def test_score_identical(self):
        sig = [1, 2, 3, 4, 5]
        mh1 = MinHashCustom(minhash_signature=sig)
        mh2 = MinHashCustom(minhash_signature=sig)
        score = MinHashCustom.calculateMinHashScore(
            mh1.getMinHash(), mh2.getMinHash()
        )
        assert score == 100.0

    def test_score_different(self):
        mh1 = MinHashCustom(minhash_signature=[1, 2, 3, 4, 5])
        mh2 = MinHashCustom(minhash_signature=[6, 7, 8, 9, 10])
        score = MinHashCustom.calculateMinHashScore(
            mh1.getMinHash(), mh2.getMinHash()
        )
        assert score < 100.0

    def test_score_against(self):
        sig1 = [1, 2, 3, 4, 5]
        sig2 = [1, 2, 99, 4, 5]
        mh1 = MinHashCustom(minhash_signature=sig1)
        mh2 = MinHashCustom(minhash_signature=sig2)
        instance_score = mh1.scoreAgainst(mh2)
        static_score = MinHashCustom.calculateMinHashScore(
            mh1.getMinHash(), mh2.getMinHash()
        )
        assert instance_score == static_score


class TestMinHashCustomBitModes:
    def test_8bit_mode(self):
        mh = MinHashCustom(minhash_bits=8)
        mh.setMinHash([10, 20, 30])
        raw = mh.getMinHash()
        arr = np.frombuffer(raw, dtype=np.uint8)
        assert list(arr) == [10, 20, 30]

    def test_32bit_mode(self):
        mh = MinHashCustom(minhash_bits=32)
        mh.setMinHash([10, 20, 30])
        raw = mh.getMinHash()
        arr = np.frombuffer(raw, dtype=np.uint32)
        assert list(arr) == [10, 20, 30]


# ============================================================================
# 2b. MinHasher
# ============================================================================


class MockILNode:
    """Mock IL node with operation and operands for normalization."""
    def __init__(self, operation, operands=None):
        self.operation = operation
        self.operands = operands or []


class MockLLILBasicBlock:
    """Mock LLIL basic block that yields IL instructions."""
    def __init__(self, instructions):
        self._instructions = instructions

    def __iter__(self):
        return iter(self._instructions)


class MockLLILFunction:
    """Mock LLIL function with basic blocks."""
    def __init__(self, basic_blocks):
        self.basic_blocks = basic_blocks


# Import MinHasher after we know the module can handle the import
from redb.extractors.decompiler.bninja.similarity.minhasher import (
    MinHasher,
    MINHASH_SIGNATURE_LENGTH,
    MINHASH_SIGNATURE_BITS,
)


class TestMinHasherMakeNgrams:
    def setup_method(self):
        # Create a minimal minhasher with a mock LLIL function
        empty_func = MockLLILFunction([])
        self.hasher = MinHasher(seed=42, il_function=empty_func)

    def test_make_ngrams_basic(self):
        result = self.hasher.make_ngrams(["a", "b", "c", "d"], n=3)
        assert result == [("a", "b", "c"), ("b", "c", "d")]

    def test_make_ngrams_short_input(self):
        result = self.hasher.make_ngrams(["a", "b"], n=3)
        assert result == []

    def test_make_ngrams_exact_n(self):
        result = self.hasher.make_ngrams(["a", "b", "c"], n=3)
        assert result == [("a", "b", "c")]


class TestMinHasherCalculate:
    def _make_llil_function(self, num_instructions=10):
        """Create a mock LLIL function with enough instructions."""
        instructions = [
            MockILNode(operation=i % 20) for i in range(num_instructions)
        ]
        bb = MockLLILBasicBlock(instructions)
        return MockLLILFunction([bb])

    def test_calculate_minhash_empty_function(self):
        # Function with < 3 LLIL instructions -> empty list
        func = self._make_llil_function(num_instructions=2)
        hasher = MinHasher(seed=42, il_function=func)
        result = hasher.calculateMinHash()
        assert result == []

    def test_calculate_minhash_deterministic(self):
        func = self._make_llil_function(num_instructions=20)
        h1 = MinHasher(seed=42, il_function=func)
        h2 = MinHasher(seed=42, il_function=func)
        assert h1.calculateMinHash() == h2.calculateMinHash()

    def test_calculate_minhash_length(self):
        func = self._make_llil_function(num_instructions=20)
        hasher = MinHasher(seed=42, il_function=func)
        result = hasher.calculateMinHash()
        assert len(result) == MINHASH_SIGNATURE_LENGTH

    def test_calculate_minhash_value_range(self):
        func = self._make_llil_function(num_instructions=20)
        hasher = MinHasher(seed=42, il_function=func)
        result = hasher.calculateMinHash()
        for val in result:
            assert 0 <= val < 2 ** MINHASH_SIGNATURE_BITS

    def test_shingle_hash_deterministic(self):
        func = self._make_llil_function(num_instructions=5)
        hasher = MinHasher(seed=42, il_function=func)
        shingle = ([1, 2], [3, 4], [5, 6])
        assert hasher.shingle_hash(shingle, 99) == hasher.shingle_hash(shingle, 99)

    def test_seed_reproducibility(self):
        func = self._make_llil_function(num_instructions=20)
        h1 = MinHasher(seed=1, il_function=func)
        h2 = MinHasher(seed=2, il_function=func)
        r1 = h1.calculateMinHash()
        r2 = h2.calculateMinHash()
        # Different seeds should (very likely) produce different results
        assert r1 != r2